Skip to content

Commit

Permalink
Stabilize AFIT and RPITIT
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Sep 13, 2023
1 parent e5fedce commit fc32ded
Show file tree
Hide file tree
Showing 210 changed files with 282 additions and 996 deletions.
70 changes: 17 additions & 53 deletions compiler/rustc_ast_lowering/src/lib.rs
Expand Up @@ -271,8 +271,6 @@ enum ImplTraitPosition {
ClosureReturn,
PointerReturn,
FnTraitReturn,
TraitReturn,
ImplReturn,
GenericDefault,
ConstTy,
StaticTy,
Expand Down Expand Up @@ -302,8 +300,6 @@ impl std::fmt::Display for ImplTraitPosition {
ImplTraitPosition::ClosureReturn => "closure return types",
ImplTraitPosition::PointerReturn => "`fn` pointer return types",
ImplTraitPosition::FnTraitReturn => "`Fn` trait return types",
ImplTraitPosition::TraitReturn => "trait method return types",
ImplTraitPosition::ImplReturn => "`impl` method return types",
ImplTraitPosition::GenericDefault => "generic parameter defaults",
ImplTraitPosition::ConstTy => "const types",
ImplTraitPosition::StaticTy => "static types",
Expand Down Expand Up @@ -334,20 +330,16 @@ impl FnDeclKind {
matches!(self, FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait)
}

fn return_impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool {
fn return_impl_trait_allowed(&self) -> bool {
match self {
FnDeclKind::Fn | FnDeclKind::Inherent => true,
FnDeclKind::Impl if tcx.features().return_position_impl_trait_in_trait => true,
FnDeclKind::Trait if tcx.features().return_position_impl_trait_in_trait => true,
FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true,
_ => false,
}
}

fn async_fn_allowed(&self, tcx: TyCtxt<'_>) -> bool {
fn async_fn_allowed(&self) -> bool {
match self {
FnDeclKind::Fn | FnDeclKind::Inherent => true,
FnDeclKind::Impl if tcx.features().async_fn_in_trait => true,
FnDeclKind::Trait if tcx.features().async_fn_in_trait => true,
FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true,
_ => false,
}
}
Expand Down Expand Up @@ -1806,52 +1798,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}));

let output = if let Some((ret_id, span)) = make_ret_async {
if !kind.async_fn_allowed(self.tcx) {
match kind {
FnDeclKind::Trait | FnDeclKind::Impl => {
self.tcx
.sess
.create_feature_err(
TraitFnAsync { fn_span, span },
sym::async_fn_in_trait,
)
.emit();
}
_ => {
self.tcx.sess.emit_err(TraitFnAsync { fn_span, span });
}
}
if !kind.async_fn_allowed() {
self.tcx.sess.emit_err(TraitFnAsync { fn_span, span });
}

let fn_def_id = self.local_def_id(fn_node_id);
self.lower_async_fn_ret_ty(&decl.output, fn_def_id, ret_id, kind)
} else {
match &decl.output {
FnRetTy::Ty(ty) => {
let context = if kind.return_impl_trait_allowed(self.tcx) {
let context = if kind.return_impl_trait_allowed() {
let fn_def_id = self.local_def_id(fn_node_id);
ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
fn_kind: kind,
}
} else {
let position = match kind {
FnDeclKind::Fn | FnDeclKind::Inherent => {
unreachable!("fn should allow in-band lifetimes")
ImplTraitContext::Disallowed(match kind {
FnDeclKind::Fn
| FnDeclKind::Inherent
| FnDeclKind::Trait
| FnDeclKind::Impl => {
unreachable!("fn should allow return-position impl trait in traits")
}
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnReturn,
FnDeclKind::Closure => ImplTraitPosition::ClosureReturn,
FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
FnDeclKind::Trait => ImplTraitPosition::TraitReturn,
FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
};
match kind {
FnDeclKind::Trait | FnDeclKind::Impl => ImplTraitContext::FeatureGated(
position,
sym::return_position_impl_trait_in_trait,
),
_ => ImplTraitContext::Disallowed(position),
}
})
};
hir::FnRetTy::Return(self.lower_ty(ty, &context))
}
Expand Down Expand Up @@ -1923,18 +1896,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let future_bound = this.lower_async_fn_output_type_to_future_bound(
output,
span,
if let FnDeclKind::Trait = fn_kind
&& !this.tcx.features().return_position_impl_trait_in_trait
{
ImplTraitContext::FeatureGated(
ImplTraitPosition::TraitReturn,
sym::return_position_impl_trait_in_trait,
)
} else {
ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
fn_kind,
}
ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
fn_kind,
},
);
arena_vec![this; future_bound]
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Expand Up @@ -67,6 +67,8 @@ declare_features! (
(accepted, associated_types, "1.0.0", None, None),
/// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
(accepted, async_await, "1.39.0", Some(50547), None),
/// Allows async functions to be declared, implemented, and used in traits.
(accepted, async_fn_in_trait, "1.66.0", Some(91611), None),
/// Allows all literals in attribute lists and values of key-value pairs.
(accepted, attr_literals, "1.30.0", Some(34981), None),
/// Allows overloading augmented assignment operations like `a += b`.
Expand Down Expand Up @@ -302,6 +304,8 @@ declare_features! (
(accepted, repr_packed, "1.33.0", Some(33158), None),
/// Allows `#[repr(transparent)]` attribute on newtype structs.
(accepted, repr_transparent, "1.28.0", Some(43036), None),
/// Allows return-position `impl Trait` in traits.
(accepted, return_position_impl_trait_in_trait, "1.65.0", Some(91611), None),
/// Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
(accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
/// Allows `Self` in type definitions (RFC 2300).
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_feature/src/active.rs
Expand Up @@ -338,8 +338,6 @@ declare_features! (
(active, associated_type_defaults, "1.2.0", Some(29661), None),
/// Allows `async || body` closures.
(active, async_closure, "1.37.0", Some(62290), None),
/// Allows async functions to be declared, implemented, and used in traits.
(active, async_fn_in_trait, "1.66.0", Some(91611), None),
/// Allows `#[track_caller]` on async functions.
(active, async_fn_track_caller, "1.73.0", Some(110011), None),
/// Allows builtin # foo() syntax
Expand Down Expand Up @@ -540,8 +538,6 @@ declare_features! (
(incomplete, repr128, "1.16.0", Some(56071), None),
/// Allows `repr(simd)` and importing the various simd intrinsics.
(active, repr_simd, "1.4.0", Some(27731), None),
/// Allows return-position `impl Trait` in traits.
(active, return_position_impl_trait_in_trait, "1.65.0", Some(91611), None),
/// Allows bounding the return type of AFIT/RPITIT.
(incomplete, return_type_notation, "1.70.0", Some(109417), None),
/// Allows `extern "rust-cold"`.
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/check/check.rs
Expand Up @@ -904,21 +904,21 @@ fn check_impl_items_against_trait<'tcx>(
let (msg, feature) = if tcx.asyncness(def_id).is_async() {
(
format!("async {descr} in trait cannot be specialized"),
sym::async_fn_in_trait,
"async functions in traits",
)
} else {
(
format!(
"{descr} with return-position `impl Trait` in trait cannot be specialized"
),
sym::return_position_impl_trait_in_trait,
"return position `impl Trait` in traits",
)
};
tcx.sess
.struct_span_err(tcx.def_span(def_id), msg)
.note(format!(
"specialization behaves in inconsistent and \
surprising ways with `#![feature({feature})]`, \
surprising ways with {feature}, \
and for now is disallowed"
))
.emit();
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Expand Up @@ -631,8 +631,6 @@ fn compare_asyncness<'tcx>(
/// For example, given the sample code:
///
/// ```
/// #![feature(return_position_impl_trait_in_trait)]
///
/// use std::ops::Deref;
///
/// trait Foo {
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_lint_defs/src/builtin.rs
Expand Up @@ -4491,7 +4491,6 @@ declare_lint! {
/// ### Example
///
/// ```rust,compile_fail
/// #![feature(return_position_impl_trait_in_trait)]
/// #![deny(refining_impl_trait)]
///
/// use std::fmt::Display;
Expand Down
17 changes: 9 additions & 8 deletions src/tools/clippy/tests/ui/enum_clike_unportable_variant.stderr
Expand Up @@ -5,51 +5,52 @@ LL | X = 0x1_0000_0000,
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::enum-clike-unportable-variant` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::enum_clike_unportable_variant)]`

error: C-like enum variant discriminant is not portable to 32-bit targets
--> $DIR/enum_clike_unportable_variant.rs:15:5
--> $DIR/enum_clike_unportable_variant.rs:17:5
|
LL | X = 0x1_0000_0000,
| ^^^^^^^^^^^^^^^^^

error: C-like enum variant discriminant is not portable to 32-bit targets
--> $DIR/enum_clike_unportable_variant.rs:18:5
--> $DIR/enum_clike_unportable_variant.rs:21:5
|
LL | A = 0xFFFF_FFFF,
| ^^^^^^^^^^^^^^^

error: C-like enum variant discriminant is not portable to 32-bit targets
--> $DIR/enum_clike_unportable_variant.rs:25:5
--> $DIR/enum_clike_unportable_variant.rs:29:5
|
LL | Z = 0xFFFF_FFFF,
| ^^^^^^^^^^^^^^^

error: C-like enum variant discriminant is not portable to 32-bit targets
--> $DIR/enum_clike_unportable_variant.rs:26:5
--> $DIR/enum_clike_unportable_variant.rs:31:5
|
LL | A = 0x1_0000_0000,
| ^^^^^^^^^^^^^^^^^

error: C-like enum variant discriminant is not portable to 32-bit targets
--> $DIR/enum_clike_unportable_variant.rs:28:5
--> $DIR/enum_clike_unportable_variant.rs:34:5
|
LL | C = (i32::MIN as isize) - 1,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: C-like enum variant discriminant is not portable to 32-bit targets
--> $DIR/enum_clike_unportable_variant.rs:34:5
--> $DIR/enum_clike_unportable_variant.rs:41:5
|
LL | Z = 0xFFFF_FFFF,
| ^^^^^^^^^^^^^^^

error: C-like enum variant discriminant is not portable to 32-bit targets
--> $DIR/enum_clike_unportable_variant.rs:35:5
--> $DIR/enum_clike_unportable_variant.rs:43:5
|
LL | A = 0x1_0000_0000,
| ^^^^^^^^^^^^^^^^^

error: C-like enum variant discriminant is not portable to 32-bit targets
--> $DIR/enum_clike_unportable_variant.rs:40:5
--> $DIR/enum_clike_unportable_variant.rs:49:5
|
LL | X = <usize as Trait>::Number,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed
@@ -1,6 +1,5 @@
#![warn(clippy::implied_bounds_in_impls)]
#![allow(dead_code)]
#![feature(return_position_impl_trait_in_trait)]

use std::ops::{Deref, DerefMut};

Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/implied_bounds_in_impls.rs
@@ -1,6 +1,5 @@
#![warn(clippy::implied_bounds_in_impls)]
#![allow(dead_code)]
#![feature(return_position_impl_trait_in_trait)]

use std::ops::{Deref, DerefMut};

Expand Down
20 changes: 10 additions & 10 deletions src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr
@@ -1,5 +1,5 @@
error: this bound is already specified as the supertrait of `DerefMut<Target = T>`
--> $DIR/implied_bounds_in_impls.rs:13:36
--> $DIR/implied_bounds_in_impls.rs:12:36
|
LL | fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> {
| ^^^^^^^^^^^^^^^^^
Expand All @@ -13,7 +13,7 @@ LL + fn deref_derefmut<T>(x: T) -> impl DerefMut<Target = T> {
|

error: this bound is already specified as the supertrait of `GenericSubtrait<U, W, U>`
--> $DIR/implied_bounds_in_impls.rs:30:37
--> $DIR/implied_bounds_in_impls.rs:29:37
|
LL | fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U>
| ^^^^^^^^^^^^^^^
Expand All @@ -25,7 +25,7 @@ LL + fn generics_implied<U, W>() -> impl GenericSubtrait<U, W, U>
|

error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>`
--> $DIR/implied_bounds_in_impls.rs:36:40
--> $DIR/implied_bounds_in_impls.rs:35:40
|
LL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}
| ^^^^^^^^^^^^^^^^^
Expand All @@ -37,7 +37,7 @@ LL + fn generics_implied_multi<V>() -> impl GenericTrait2<V> + GenericSubtrait<(
|

error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>`
--> $DIR/implied_bounds_in_impls.rs:36:60
--> $DIR/implied_bounds_in_impls.rs:35:60
|
LL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}
| ^^^^^^^^^^^^^^^^
Expand All @@ -49,7 +49,7 @@ LL + fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericSubtrait<
|

error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>`
--> $DIR/implied_bounds_in_impls.rs:38:44
--> $DIR/implied_bounds_in_impls.rs:37:44
|
LL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>
| ^^^^^^^^^^^^^^^
Expand All @@ -61,7 +61,7 @@ LL + fn generics_implied_multi2<T, V>() -> impl GenericTrait2<V> + GenericSubtra
|

error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>`
--> $DIR/implied_bounds_in_impls.rs:38:62
--> $DIR/implied_bounds_in_impls.rs:37:62
|
LL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>
| ^^^^^^^^^^^^^^^^
Expand All @@ -73,7 +73,7 @@ LL + fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericSubtrai
|

error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, ()>`
--> $DIR/implied_bounds_in_impls.rs:48:28
--> $DIR/implied_bounds_in_impls.rs:47:28
|
LL | fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {}
| ^^^^^^^^^^^^^^^^^
Expand All @@ -85,7 +85,7 @@ LL + fn generics_same() -> impl GenericSubtrait<(), i32, ()> {}
|

error: this bound is already specified as the supertrait of `DerefMut<Target = u8>`
--> $DIR/implied_bounds_in_impls.rs:52:20
--> $DIR/implied_bounds_in_impls.rs:51:20
|
LL | fn f() -> impl Deref + DerefMut<Target = u8>;
| ^^^^^
Expand All @@ -97,7 +97,7 @@ LL + fn f() -> impl DerefMut<Target = u8>;
|

error: this bound is already specified as the supertrait of `DerefMut<Target = u8>`
--> $DIR/implied_bounds_in_impls.rs:57:20
--> $DIR/implied_bounds_in_impls.rs:56:20
|
LL | fn f() -> impl Deref + DerefMut<Target = u8> {
| ^^^^^
Expand All @@ -109,7 +109,7 @@ LL + fn f() -> impl DerefMut<Target = u8> {
|

error: this bound is already specified as the supertrait of `DerefMut<Target = u8>`
--> $DIR/implied_bounds_in_impls.rs:63:20
--> $DIR/implied_bounds_in_impls.rs:62:20
|
LL | fn f() -> impl Deref + DerefMut<Target = u8> {
| ^^^^^
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/unused_async.rs
@@ -1,5 +1,4 @@
#![warn(clippy::unused_async)]
#![feature(async_fn_in_trait)]
#![allow(incomplete_features)]

use std::future::Future;
Expand Down

0 comments on commit fc32ded

Please sign in to comment.