From 973bbfbd23df736dd3a257e42c6cd7e3fe5b0281 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 6 Feb 2024 19:35:57 +0000 Subject: [PATCH 1/3] No more associated type bounds in dyn trait --- compiler/rustc_ast_lowering/messages.ftl | 6 +- compiler/rustc_ast_lowering/src/errors.rs | 5 +- compiler/rustc_ast_lowering/src/lib.rs | 59 ++------------- .../assoc-type-eq-with-dyn-atb-fail.rs | 2 +- .../assoc-type-eq-with-dyn-atb-fail.stderr | 9 +-- .../bad-universal-in-dyn-in-where-clause.rs | 2 +- ...ad-universal-in-dyn-in-where-clause.stderr | 2 +- .../bad-universal-in-impl-sig.rs | 2 +- .../bad-universal-in-impl-sig.stderr | 2 +- tests/ui/associated-type-bounds/duplicate.rs | 7 -- .../associated-type-bounds/duplicate.stderr | 26 +------ .../dyn-impl-trait-type.rs | 66 ----------------- .../dyn-rpit-and-let.rs | 73 ------------------- tests/ui/associated-type-bounds/elision.rs | 4 +- .../ui/associated-type-bounds/elision.stderr | 15 +--- .../ui/associated-type-bounds/fn-dyn-apit.rs | 61 ---------------- tests/ui/associated-type-bounds/inside-adt.rs | 18 ++--- .../associated-type-bounds/inside-adt.stderr | 18 ++--- .../ui/associated-type-bounds/issue-104916.rs | 2 +- .../issue-104916.stderr | 2 +- .../feature-gate-associated_type_bounds.rs | 11 --- ...feature-gate-associated_type_bounds.stderr | 36 ++------- 22 files changed, 55 insertions(+), 373 deletions(-) delete mode 100644 tests/ui/associated-type-bounds/dyn-impl-trait-type.rs delete mode 100644 tests/ui/associated-type-bounds/dyn-rpit-and-let.rs delete mode 100644 tests/ui/associated-type-bounds/fn-dyn-apit.rs diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 37e45379ba9a2..9c151ec80eefe 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -8,6 +8,9 @@ ast_lowering_arbitrary_expression_in_pattern = ast_lowering_argument = argument +ast_lowering_assoc_ty_binding_in_dyn = + associated type bounds are not allowed in `dyn` types + ast_lowering_assoc_ty_parentheses = parenthesized generic arguments cannot be used in associated type constraints @@ -100,9 +103,6 @@ ast_lowering_match_arm_with_no_body = `match` arm with no body .suggestion = add a body after the pattern -ast_lowering_misplaced_assoc_ty_binding = - associated type bounds are only allowed in where clauses and function signatures, not in {$position} - ast_lowering_misplaced_double_dot = `..` patterns are not allowed here .note = only allowed in tuple, tuple struct, and slice patterns diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 6225358569573..fba8ea206f140 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -94,11 +94,10 @@ pub struct MisplacedImplTrait<'a> { } #[derive(Diagnostic)] -#[diag(ast_lowering_misplaced_assoc_ty_binding)] -pub struct MisplacedAssocTyBinding<'a> { +#[diag(ast_lowering_assoc_ty_binding_in_dyn)] +pub struct MisplacedAssocTyBinding { #[primary_span] pub span: Span, - pub position: DiagnosticArgFromDisplay<'a>, } #[derive(Diagnostic, Clone, Copy)] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4ef9c7607be5e..48cc301219a87 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1085,33 +1085,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } AssocConstraintKind::Bound { bounds } => { enum DesugarKind { - ImplTrait, - Error(ImplTraitPosition), + Error, Bound, } // Piggy-back on the `impl Trait` context to figure out the correct behavior. let desugar_kind = match itctx { - // in an argument, RPIT, or TAIT, if we are within a dyn type: - // - // fn foo(x: dyn Iterator) - // - // then desugar to: - // - // fn foo(x: dyn Iterator) - // - // This is because dyn traits must have all of their associated types specified. - ImplTraitContext::ReturnPositionOpaqueTy { .. } - | ImplTraitContext::TypeAliasesOpaqueTy { .. } - | ImplTraitContext::Universal - if self.is_in_dyn_type => - { - DesugarKind::ImplTrait - } - - ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => { - DesugarKind::Error(position) - } + _ if self.is_in_dyn_type => DesugarKind::Error, // We are in the parameter position, but not within a dyn type: // @@ -1124,32 +1104,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; match desugar_kind { - DesugarKind::ImplTrait => { - // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by - // constructing the HIR for `impl bounds...` and then lowering that. - - let impl_trait_node_id = self.next_node_id(); - // Shift `impl Trait` lifetime captures from the associated type bound's - // node id to the opaque node id, so that the opaque can actually use - // these lifetime bounds. - self.resolver - .remap_extra_lifetime_params(constraint.id, impl_trait_node_id); - - self.with_dyn_type_scope(false, |this| { - let node_id = this.next_node_id(); - let ty = this.lower_ty( - &Ty { - id: node_id, - kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), - span: this.lower_span(constraint.span), - tokens: None, - }, - itctx, - ); - - hir::TypeBindingKind::Equality { term: ty.into() } - }) - } DesugarKind::Bound => { // Desugar `AssocTy: Bounds` into a type binding where the // later desugars into a trait predicate. @@ -1157,11 +1111,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBindingKind::Constraint { bounds } } - DesugarKind::Error(position) => { - let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding { - span: constraint.span, - position: DiagnosticArgFromDisplay(&position), - }); + DesugarKind::Error => { + let guar = self + .dcx() + .emit_err(errors::MisplacedAssocTyBinding { span: constraint.span }); let err_ty = &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar))); hir::TypeBindingKind::Equality { term: err_ty.into() } diff --git a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs index 4c36289f47b85..8a580e191869b 100644 --- a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs +++ b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs @@ -28,9 +28,9 @@ impl Bar for AssocNoCopy { impl Thing for AssocNoCopy { type Out = Box>; + //~^ ERROR associated type bounds are not allowed in `dyn` types fn func() -> Self::Out { - //~^ ERROR the trait bound `String: Copy` is not satisfied Box::new(AssocNoCopy) } } diff --git a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr index 7942992874da5..2d38bbd8c923e 100644 --- a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr +++ b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr @@ -1,9 +1,8 @@ -error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:32:18 +error: associated type bounds are not allowed in `dyn` types + --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:30:28 | -LL | fn func() -> Self::Out { - | ^^^^^^^^^ the trait `Copy` is not implemented for `String` +LL | type Out = Box>; + | ^^^^^^^^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs index 8cab1f66c2709..81c8fe829f978 100644 --- a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs +++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs @@ -7,7 +7,7 @@ trait B { fn f() where dyn for<'j> B:, - //~^ ERROR associated type bounds are only allowed in where clauses and function signatures + //~^ ERROR associated type bounds are not allowed in `dyn` types { } diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr index fe300a7de427b..7d9870c72d481 100644 --- a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr +++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr @@ -1,4 +1,4 @@ -error: associated type bounds are only allowed in where clauses and function signatures, not in bounds +error: associated type bounds are not allowed in `dyn` types --> $DIR/bad-universal-in-dyn-in-where-clause.rs:9:19 | LL | dyn for<'j> B:, diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs index 1d5d181efcc01..f465123f34c8b 100644 --- a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs +++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs @@ -8,6 +8,6 @@ trait Trait2 {} // It's not possible to insert a universal `impl Trait` here! impl dyn Trait {} -//~^ ERROR associated type bounds are only allowed in where clauses and function signatures +//~^ ERROR associated type bounds are not allowed in `dyn` types fn main() {} diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr index 7bdb2c5a7c292..8855bd9c31230 100644 --- a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr +++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr @@ -1,4 +1,4 @@ -error: associated type bounds are only allowed in where clauses and function signatures, not in impl headers +error: associated type bounds are not allowed in `dyn` types --> $DIR/bad-universal-in-impl-sig.rs:10:16 | LL | impl dyn Trait {} diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs index 036f8ede1b3b7..54c8cd3fde0d7 100644 --- a/tests/ui/associated-type-bounds/duplicate.rs +++ b/tests/ui/associated-type-bounds/duplicate.rs @@ -261,11 +261,4 @@ trait TRA3 { //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] } -type TADyn1 = dyn Iterator; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -type TADyn2 = Box>; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -type TADyn3 = dyn Iterator; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - fn main() {} diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr index bf6aab96dc726..9816d11a40a8b 100644 --- a/tests/ui/associated-type-bounds/duplicate.stderr +++ b/tests/ui/associated-type-bounds/duplicate.stderr @@ -6,30 +6,6 @@ LL | struct SI1> { | | | `Item` bound here first -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:264:40 - | -LL | type TADyn1 = dyn Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:266:44 - | -LL | type TADyn2 = Box>; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:268:43 - | -LL | type TADyn3 = dyn Iterator; - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified --> $DIR/duplicate.rs:11:36 | @@ -631,7 +607,7 @@ LL | Self: Iterator, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 75 previous errors +error: aborting due to 72 previous errors Some errors have detailed explanations: E0282, E0719. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs b/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs deleted file mode 100644 index 079c44b3a598d..0000000000000 --- a/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs +++ /dev/null @@ -1,66 +0,0 @@ -// run-pass - -#![feature(associated_type_bounds)] - -use std::ops::Add; - -trait Tr1 { type As1; fn mk(&self) -> Self::As1; } -trait Tr2<'a> { fn tr2(self) -> &'a Self; } //~ WARN method `tr2` is never used - -fn assert_copy(x: T) { let _x = x; let _x = x; } -fn assert_static(_: T) {} -fn assert_forall_tr2 Tr2<'a>>(_: T) {} - -struct S1; -#[derive(Copy, Clone)] -struct S2; -impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } - -type Et1 = Box>; -fn def_et1() -> Et1 { Box::new(S1) } -pub fn use_et1() { assert_copy(def_et1().mk()); } - -type Et2 = Box>; -fn def_et2() -> Et2 { Box::new(S1) } -pub fn use_et2() { assert_static(def_et2().mk()); } - -type Et3 = Box>>>>; -fn def_et3() -> Et3 { - struct A; - impl Tr1 for A { - type As1 = core::ops::Range; - fn mk(&self) -> Self::As1 { 0..10 } - } - Box::new(A) -} -pub fn use_et3() { - let _0 = def_et3().mk().clone(); - let mut s = 0u8; - for _1 in _0 { - let _2 = _1 + 1u8; - s += _2.into(); - } - assert_eq!(s, (0..10).map(|x| x + 1).sum()); -} - -type Et4 = Box Tr2<'a>>>; -fn def_et4() -> Et4 { - #[derive(Copy, Clone)] - struct A; - impl Tr1 for A { - type As1 = A; - fn mk(&self) -> A { A } - } - impl<'a> Tr2<'a> for A { - fn tr2(self) -> &'a Self { &A } - } - Box::new(A) -} -pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } - -fn main() { - use_et1(); - use_et2(); - use_et3(); - use_et4(); -} diff --git a/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs b/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs deleted file mode 100644 index 49e5e72f225e2..0000000000000 --- a/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs +++ /dev/null @@ -1,73 +0,0 @@ -// run-pass - -// FIXME: uncomment let binding types below when `impl_trait_in_bindings` feature is fixed. - -#![feature(associated_type_bounds)] - -use std::ops::Add; - -trait Tr1 { type As1; fn mk(&self) -> Self::As1; } -trait Tr2<'a> { fn tr2(self) -> &'a Self; } //~ WARN method `tr2` is never used - -fn assert_copy(x: T) { let _x = x; let _x = x; } -fn assert_static(_: T) {} -fn assert_forall_tr2 Tr2<'a>>(_: T) {} - -struct S1; -#[derive(Copy, Clone)] -struct S2; -impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } - -fn def_et1() -> Box> { - let x /* : Box> */ = Box::new(S1); - x -} -pub fn use_et1() { assert_copy(def_et1().mk()); } - -fn def_et2() -> Box> { - let x /* : Box> */ = Box::new(S1); - x -} -pub fn use_et2() { assert_static(def_et2().mk()); } - -fn def_et3() -> Box>>>> { - struct A; - impl Tr1 for A { - type As1 = core::ops::Range; - fn mk(&self) -> Self::As1 { 0..10 } - } - let x /* : Box>>>> */ - = Box::new(A); - x -} -pub fn use_et3() { - let _0 = def_et3().mk().clone(); - let mut s = 0u8; - for _1 in _0 { - let _2 = _1 + 1u8; - s += _2.into(); - } - assert_eq!(s, (0..10).map(|x| x + 1).sum()); -} - -fn def_et4() -> Box Tr2<'a>>> { - #[derive(Copy, Clone)] - struct A; - impl Tr1 for A { - type As1 = A; - fn mk(&self) -> A { A } - } - impl<'a> Tr2<'a> for A { - fn tr2(self) -> &'a Self { &A } - } - let x /* : Box Tr2<'a>>> */ = Box::new(A); - x -} -pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } - -fn main() { - use_et1(); - use_et2(); - use_et3(); - use_et4(); -} diff --git a/tests/ui/associated-type-bounds/elision.rs b/tests/ui/associated-type-bounds/elision.rs index d00def571666b..5d7ed940ac69b 100644 --- a/tests/ui/associated-type-bounds/elision.rs +++ b/tests/ui/associated-type-bounds/elision.rs @@ -3,7 +3,7 @@ // The same thing should happen for constraints in dyn trait. fn f(x: &mut dyn Iterator>) -> Option<&'_ ()> { x.next() } -//~^ ERROR missing lifetime specifier -//~| ERROR mismatched types +//~^ ERROR associated type bounds are not allowed in `dyn` types +//~| ERROR missing lifetime specifier fn main() {} diff --git a/tests/ui/associated-type-bounds/elision.stderr b/tests/ui/associated-type-bounds/elision.stderr index a29e32a784fe4..70302d25b2b45 100644 --- a/tests/ui/associated-type-bounds/elision.stderr +++ b/tests/ui/associated-type-bounds/elision.stderr @@ -10,19 +10,12 @@ help: consider introducing a named lifetime parameter LL | fn f<'a>(x: &'a mut dyn Iterator>) -> Option<&'a ()> { x.next() } | ++++ ++ ~~ ~~ -error[E0308]: mismatched types - --> $DIR/elision.rs:5:79 +error: associated type bounds are not allowed in `dyn` types + --> $DIR/elision.rs:5:27 | LL | fn f(x: &mut dyn Iterator>) -> Option<&'_ ()> { x.next() } - | ----------------------------- -------------- ^^^^^^^^ expected `Option<&()>`, found `Option>` - | | | - | | expected `Option<&()>` because of return type - | found this type parameter - | - = note: expected enum `Option<&()>` - found enum `Option>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors -Some errors have detailed explanations: E0106, E0308. -For more information about an error, try `rustc --explain E0106`. +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/associated-type-bounds/fn-dyn-apit.rs b/tests/ui/associated-type-bounds/fn-dyn-apit.rs deleted file mode 100644 index c4e8092c211d6..0000000000000 --- a/tests/ui/associated-type-bounds/fn-dyn-apit.rs +++ /dev/null @@ -1,61 +0,0 @@ -// run-pass -// aux-build:fn-dyn-aux.rs - -#![allow(unused)] -#![feature(associated_type_bounds)] - -extern crate fn_dyn_aux; - -use fn_dyn_aux::*; - -// ATB, APIT (dyn trait): - -fn dyn_apit_bound(beta: &dyn Beta) -> usize { - desugared_bound(beta) -} - -fn dyn_apit_bound_region(beta: &dyn Beta) -> usize { - desugared_bound_region(beta) -} - -fn dyn_apit_bound_multi( - beta: &(dyn Beta + Send) -) -> usize { - desugared_bound_multi(beta) -} - -fn dyn_apit_bound_region_forall( - beta: &dyn Beta Epsilon<'a>> -) -> usize { - desugared_bound_region_forall(beta) -} - -fn dyn_apit_bound_region_forall2( - beta: &dyn Beta Epsilon<'a, Zeta: Eta>> -) -> usize { - desugared_bound_region_forall2(beta) -} - -fn dyn_apit_bound_nested( - beta: &dyn Beta> -) -> usize { - desugared_bound_nested(beta) -} - -fn dyn_apit_bound_nested2( - beta: &dyn Beta> -) -> usize { - desugared_bound_nested(beta) -} - -fn main() { - let beta = BetaType; - let _gamma = beta.gamma(); - - assert_eq!(42, dyn_apit_bound(&beta)); - assert_eq!(24, dyn_apit_bound_region(&beta)); - assert_eq!(42 + 24 + 1337, dyn_apit_bound_multi(&beta)); - assert_eq!(7331 * 2, dyn_apit_bound_region_forall(&beta)); - assert_eq!(42 + 1337, dyn_apit_bound_nested(&beta)); - assert_eq!(42 + 1337, dyn_apit_bound_nested2(&beta)); -} diff --git a/tests/ui/associated-type-bounds/inside-adt.rs b/tests/ui/associated-type-bounds/inside-adt.rs index 057966941dc09..2b4b060983e03 100644 --- a/tests/ui/associated-type-bounds/inside-adt.rs +++ b/tests/ui/associated-type-bounds/inside-adt.rs @@ -3,24 +3,24 @@ use std::mem::ManuallyDrop; struct S1 { f: dyn Iterator } -//~^ ERROR associated type bounds are only allowed in where clauses and function signatures +//~^ ERROR associated type bounds are not allowed in `dyn` types struct S2 { f: Box> } -//~^ ERROR associated type bounds are only allowed in where clauses and function signatures +//~^ ERROR associated type bounds are not allowed in `dyn` types struct S3 { f: dyn Iterator } -//~^ ERROR associated type bounds are only allowed in where clauses and function signatures +//~^ ERROR associated type bounds are not allowed in `dyn` types enum E1 { V(dyn Iterator) } -//~^ ERROR associated type bounds are only allowed in where clauses and function signatures +//~^ ERROR associated type bounds are not allowed in `dyn` types enum E2 { V(Box>) } -//~^ ERROR associated type bounds are only allowed in where clauses and function signatures +//~^ ERROR associated type bounds are not allowed in `dyn` types enum E3 { V(dyn Iterator) } -//~^ ERROR associated type bounds are only allowed in where clauses and function signatures +//~^ ERROR associated type bounds are not allowed in `dyn` types union U1 { f: ManuallyDrop> } -//~^ ERROR associated type bounds are only allowed in where clauses and function signatures +//~^ ERROR associated type bounds are not allowed in `dyn` types union U2 { f: ManuallyDrop>> } -//~^ ERROR associated type bounds are only allowed in where clauses and function signatures +//~^ ERROR associated type bounds are not allowed in `dyn` types union U3 { f: ManuallyDrop> } -//~^ ERROR associated type bounds are only allowed in where clauses and function signatures +//~^ ERROR associated type bounds are not allowed in `dyn` types fn main() {} diff --git a/tests/ui/associated-type-bounds/inside-adt.stderr b/tests/ui/associated-type-bounds/inside-adt.stderr index f848bd798ee0a..ef45fae8f2a1c 100644 --- a/tests/ui/associated-type-bounds/inside-adt.stderr +++ b/tests/ui/associated-type-bounds/inside-adt.stderr @@ -1,52 +1,52 @@ -error: associated type bounds are only allowed in where clauses and function signatures, not in field types +error: associated type bounds are not allowed in `dyn` types --> $DIR/inside-adt.rs:5:29 | LL | struct S1 { f: dyn Iterator } | ^^^^^^^^^^ -error: associated type bounds are only allowed in where clauses and function signatures, not in field types +error: associated type bounds are not allowed in `dyn` types --> $DIR/inside-adt.rs:7:33 | LL | struct S2 { f: Box> } | ^^^^^^^^^^ -error: associated type bounds are only allowed in where clauses and function signatures, not in field types +error: associated type bounds are not allowed in `dyn` types --> $DIR/inside-adt.rs:9:29 | LL | struct S3 { f: dyn Iterator } | ^^^^^^^^^^^^^ -error: associated type bounds are only allowed in where clauses and function signatures, not in field types +error: associated type bounds are not allowed in `dyn` types --> $DIR/inside-adt.rs:12:26 | LL | enum E1 { V(dyn Iterator) } | ^^^^^^^^^^ -error: associated type bounds are only allowed in where clauses and function signatures, not in field types +error: associated type bounds are not allowed in `dyn` types --> $DIR/inside-adt.rs:14:30 | LL | enum E2 { V(Box>) } | ^^^^^^^^^^ -error: associated type bounds are only allowed in where clauses and function signatures, not in field types +error: associated type bounds are not allowed in `dyn` types --> $DIR/inside-adt.rs:16:26 | LL | enum E3 { V(dyn Iterator) } | ^^^^^^^^^^^^^ -error: associated type bounds are only allowed in where clauses and function signatures, not in field types +error: associated type bounds are not allowed in `dyn` types --> $DIR/inside-adt.rs:19:41 | LL | union U1 { f: ManuallyDrop> } | ^^^^^^^^^^ -error: associated type bounds are only allowed in where clauses and function signatures, not in field types +error: associated type bounds are not allowed in `dyn` types --> $DIR/inside-adt.rs:21:45 | LL | union U2 { f: ManuallyDrop>> } | ^^^^^^^^^^ -error: associated type bounds are only allowed in where clauses and function signatures, not in field types +error: associated type bounds are not allowed in `dyn` types --> $DIR/inside-adt.rs:23:41 | LL | union U3 { f: ManuallyDrop> } diff --git a/tests/ui/associated-type-bounds/issue-104916.rs b/tests/ui/associated-type-bounds/issue-104916.rs index 3361fa011ed8e..ee29a0a2fc491 100644 --- a/tests/ui/associated-type-bounds/issue-104916.rs +++ b/tests/ui/associated-type-bounds/issue-104916.rs @@ -7,7 +7,7 @@ trait B { fn f() where dyn for<'j> B:, - //~^ ERROR: associated type bounds are only allowed in where clauses and function signatures + //~^ ERROR: associated type bounds are not allowed in `dyn` types { } diff --git a/tests/ui/associated-type-bounds/issue-104916.stderr b/tests/ui/associated-type-bounds/issue-104916.stderr index 65c89735c5dcc..e8618b7210369 100644 --- a/tests/ui/associated-type-bounds/issue-104916.stderr +++ b/tests/ui/associated-type-bounds/issue-104916.stderr @@ -1,4 +1,4 @@ -error: associated type bounds are only allowed in where clauses and function signatures, not in bounds +error: associated type bounds are not allowed in `dyn` types --> $DIR/issue-104916.rs:9:19 | LL | dyn for<'j> B:, diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs index f87d3aab635c0..717da41f8713d 100644 --- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs +++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs @@ -42,31 +42,20 @@ type _TaWhere1 where T: Iterator = T; fn _apit(_: impl Tr1) {} //~^ ERROR associated type bounds are unstable -fn _apit_dyn(_: &dyn Tr1) {} -//~^ ERROR associated type bounds are unstable fn _rpit() -> impl Tr1 { S1 } //~^ ERROR associated type bounds are unstable -fn _rpit_dyn() -> Box> { Box::new(S1) } -//~^ ERROR associated type bounds are unstable - const _cdef: impl Tr1 = S1; //~^ ERROR associated type bounds are unstable //~| ERROR `impl Trait` is not allowed in const types -// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. -// const _cdef_dyn: &dyn Tr1 = &S1; static _sdef: impl Tr1 = S1; //~^ ERROR associated type bounds are unstable //~| ERROR `impl Trait` is not allowed in static types -// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. -// static _sdef_dyn: &dyn Tr1 = &S1; fn main() { let _: impl Tr1 = S1; //~^ ERROR associated type bounds are unstable //~| ERROR `impl Trait` is not allowed in the type of variable bindings - // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. - // let _: &dyn Tr1 = &S1; } diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr index 855a29953f1b0..1838eab5cda5f 100644 --- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -69,17 +69,7 @@ LL | fn _apit(_: impl Tr1) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:45:26 - | -LL | fn _apit_dyn(_: &dyn Tr1) {} - | ^^^^^^^^^ - | - = note: see issue #52662 for more information - = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:48:24 + --> $DIR/feature-gate-associated_type_bounds.rs:46:24 | LL | fn _rpit() -> impl Tr1 { S1 } | ^^^^^^^^^ @@ -89,17 +79,7 @@ LL | fn _rpit() -> impl Tr1 { S1 } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:51:31 - | -LL | fn _rpit_dyn() -> Box> { Box::new(S1) } - | ^^^^^^^^^ - | - = note: see issue #52662 for more information - = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:54:23 + --> $DIR/feature-gate-associated_type_bounds.rs:49:23 | LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^ @@ -109,7 +89,7 @@ LL | const _cdef: impl Tr1 = S1; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:60:24 + --> $DIR/feature-gate-associated_type_bounds.rs:53:24 | LL | static _sdef: impl Tr1 = S1; | ^^^^^^^^^ @@ -119,7 +99,7 @@ LL | static _sdef: impl Tr1 = S1; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:67:21 + --> $DIR/feature-gate-associated_type_bounds.rs:58:21 | LL | let _: impl Tr1 = S1; | ^^^^^^^^^ @@ -129,7 +109,7 @@ LL | let _: impl Tr1 = S1; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in const types - --> $DIR/feature-gate-associated_type_bounds.rs:54:14 + --> $DIR/feature-gate-associated_type_bounds.rs:49:14 | LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ @@ -137,7 +117,7 @@ LL | const _cdef: impl Tr1 = S1; = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in static types - --> $DIR/feature-gate-associated_type_bounds.rs:60:15 + --> $DIR/feature-gate-associated_type_bounds.rs:53:15 | LL | static _sdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ @@ -145,14 +125,14 @@ LL | static _sdef: impl Tr1 = S1; = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/feature-gate-associated_type_bounds.rs:67:12 + --> $DIR/feature-gate-associated_type_bounds.rs:58:12 | LL | let _: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ | = note: `impl Trait` is only allowed in arguments and return types of functions and methods -error: aborting due to 16 previous errors +error: aborting due to 14 previous errors Some errors have detailed explanations: E0562, E0658. For more information about an error, try `rustc --explain E0562`. From fde695a2d19fc13a5773b8e9168341c67a21912e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 6 Feb 2024 19:48:16 +0000 Subject: [PATCH 2/3] Add a helpful suggestion --- compiler/rustc_ast_lowering/messages.ftl | 1 + compiler/rustc_ast_lowering/src/errors.rs | 2 + compiler/rustc_ast_lowering/src/lib.rs | 63 +++++++++---------- .../assoc-type-eq-with-dyn-atb-fail.stderr | 5 ++ .../dyn-impl-trait-type.stderr | 12 ---- .../dyn-rpit-and-let.stderr | 12 ---- .../ui/associated-type-bounds/elision.stderr | 5 ++ 7 files changed, 43 insertions(+), 57 deletions(-) delete mode 100644 tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr delete mode 100644 tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 9c151ec80eefe..e87cf05713cd3 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -10,6 +10,7 @@ ast_lowering_argument = argument ast_lowering_assoc_ty_binding_in_dyn = associated type bounds are not allowed in `dyn` types + .suggestion = use `impl Trait` to introduce a type instead ast_lowering_assoc_ty_parentheses = parenthesized generic arguments cannot be used in associated type constraints diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index fba8ea206f140..274e6b7458c61 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -98,6 +98,8 @@ pub struct MisplacedImplTrait<'a> { pub struct MisplacedAssocTyBinding { #[primary_span] pub span: Span, + #[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")] + pub suggestion: Option, } #[derive(Diagnostic, Clone, Copy)] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 48cc301219a87..7c89600fa281c 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1084,41 +1084,38 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBindingKind::Equality { term } } AssocConstraintKind::Bound { bounds } => { - enum DesugarKind { - Error, - Bound, - } - - // Piggy-back on the `impl Trait` context to figure out the correct behavior. - let desugar_kind = match itctx { - _ if self.is_in_dyn_type => DesugarKind::Error, - - // We are in the parameter position, but not within a dyn type: - // - // fn foo(x: impl Iterator) - // - // so we leave it as is and this gets expanded in astconv to a bound like - // `::Item: Debug` where `T` is the type parameter for the - // `impl Iterator`. - _ => DesugarKind::Bound, - }; + // Disallow ATB in dyn types + if self.is_in_dyn_type { + let suggestion = match itctx { + ImplTraitContext::ReturnPositionOpaqueTy { .. } + | ImplTraitContext::TypeAliasesOpaqueTy { .. } + | ImplTraitContext::Universal => { + let bound_end_span = constraint + .gen_args + .as_ref() + .map_or(constraint.ident.span, |args| args.span()); + if bound_end_span.eq_ctxt(constraint.span) { + Some(self.tcx.sess.source_map().next_point(bound_end_span)) + } else { + None + } + } + _ => None, + }; - match desugar_kind { - DesugarKind::Bound => { - // Desugar `AssocTy: Bounds` into a type binding where the - // later desugars into a trait predicate. - let bounds = self.lower_param_bounds(bounds, itctx); + let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding { + span: constraint.span, + suggestion, + }); + let err_ty = + &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar))); + hir::TypeBindingKind::Equality { term: err_ty.into() } + } else { + // Desugar `AssocTy: Bounds` into a type binding where the + // later desugars into a trait predicate. + let bounds = self.lower_param_bounds(bounds, itctx); - hir::TypeBindingKind::Constraint { bounds } - } - DesugarKind::Error => { - let guar = self - .dcx() - .emit_err(errors::MisplacedAssocTyBinding { span: constraint.span }); - let err_ty = - &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar))); - hir::TypeBindingKind::Equality { term: err_ty.into() } - } + hir::TypeBindingKind::Constraint { bounds } } } }; diff --git a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr index 2d38bbd8c923e..ad5409094118d 100644 --- a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr +++ b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr @@ -3,6 +3,11 @@ error: associated type bounds are not allowed in `dyn` types | LL | type Out = Box>; | ^^^^^^^^^^^ + | +help: use `impl Trait` to introduce a type instead + | +LL | type Out = Box>; + | ~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr b/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr deleted file mode 100644 index 2e26a434f5d34..0000000000000 --- a/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: method `tr2` is never used - --> $DIR/dyn-impl-trait-type.rs:8:20 - | -LL | trait Tr2<'a> { fn tr2(self) -> &'a Self; } - | --- ^^^ - | | - | method in this trait - | - = note: `#[warn(dead_code)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr b/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr deleted file mode 100644 index 9eddbe462847d..0000000000000 --- a/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: method `tr2` is never used - --> $DIR/dyn-rpit-and-let.rs:10:20 - | -LL | trait Tr2<'a> { fn tr2(self) -> &'a Self; } - | --- ^^^ - | | - | method in this trait - | - = note: `#[warn(dead_code)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/associated-type-bounds/elision.stderr b/tests/ui/associated-type-bounds/elision.stderr index 70302d25b2b45..749dffdc4d318 100644 --- a/tests/ui/associated-type-bounds/elision.stderr +++ b/tests/ui/associated-type-bounds/elision.stderr @@ -15,6 +15,11 @@ error: associated type bounds are not allowed in `dyn` types | LL | fn f(x: &mut dyn Iterator>) -> Option<&'_ ()> { x.next() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `impl Trait` to introduce a type instead + | +LL | fn f(x: &mut dyn Iterator>) -> Option<&'_ ()> { x.next() } + | ~~~~~~ error: aborting due to 2 previous errors From e6f5af967132139ba584ad3c04df8dac83dc2640 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 10 Feb 2024 03:52:13 +0000 Subject: [PATCH 3/3] Remove unused fn --- compiler/rustc_ast_lowering/src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 7c89600fa281c..5f7439060b3c9 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -197,7 +197,6 @@ trait ResolverAstLoweringExt { fn get_label_res(&self, id: NodeId) -> Option; fn get_lifetime_res(&self, id: NodeId) -> Option; fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>; - fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId); } impl ResolverAstLoweringExt for ResolverAstLowering { @@ -256,11 +255,6 @@ impl ResolverAstLoweringExt for ResolverAstLowering { fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> { self.extra_lifetime_params_map.remove(&id).unwrap_or_default() } - - fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId) { - let lifetimes = self.extra_lifetime_params_map.remove(&from).unwrap_or_default(); - self.extra_lifetime_params_map.insert(to, lifetimes); - } } /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,