diff options
| author | Michael Goulet <michael@errs.io> | 2023-02-14 20:07:33 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-02-22 21:52:26 +0000 |
| commit | deb135748d8489118e968b229c5c92d4fa18a1cf (patch) | |
| tree | fd180497b63ca09f9fdd527f1838dc57f1f2dcff | |
| parent | e7c490892f440afb1e34b3c2315aca04f51cd070 (diff) | |
| download | rust-deb135748d8489118e968b229c5c92d4fa18a1cf.tar.gz rust-deb135748d8489118e968b229c5c92d4fa18a1cf.zip | |
Suppress duplicated errors for associated type bounds in object types
6 files changed, 56 insertions, 137 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 60391f77449..9faf112f4a1 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1011,8 +1011,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBindingKind::Equality { term } } AssocConstraintKind::Bound { bounds } => { + enum DesugarKind<'a> { + ImplTrait, + Error(&'a ImplTraitPosition), + Bound, + } + // Piggy-back on the `impl Trait` context to figure out the correct behavior. - let (desugar_to_impl_trait, itctx) = match itctx { + let desugar_kind = match itctx { // We are in the return position: // // fn foo() -> impl Iterator<Item: Debug> @@ -1021,7 +1027,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // fn foo() -> impl Iterator<Item = impl Debug> ImplTraitContext::ReturnPositionOpaqueTy { .. } - | ImplTraitContext::TypeAliasesOpaqueTy { .. } => (true, itctx), + | ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait, // We are in the argument position, but within a dyn type: // @@ -1030,7 +1036,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // so desugar to // // fn foo(x: dyn Iterator<Item = impl Debug>) - ImplTraitContext::Universal if self.is_in_dyn_type => (true, itctx), + ImplTraitContext::Universal if self.is_in_dyn_type => DesugarKind::ImplTrait, // In `type Foo = dyn Iterator<Item: Debug>` we desugar to // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the @@ -1039,11 +1045,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // FIXME: this is only needed until `impl Trait` is allowed in type aliases. ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => { - self.tcx.sess.emit_err(errors::MisplacedAssocTyBinding { - span: constraint.span, - position: DiagnosticArgFromDisplay(position), - }); - (false, itctx) + DesugarKind::Error(position) } // We are in the parameter position, but not within a dyn type: @@ -1053,35 +1055,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // so we leave it as is and this gets expanded in astconv to a bound like // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the // `impl Iterator`. - _ => (false, itctx), + _ => DesugarKind::Bound, }; - if desugar_to_impl_trait { - // 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(); - - 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, - ); + 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. - hir::TypeBindingKind::Equality { term: 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); + let impl_trait_node_id = self.next_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::Constraint { bounds } + hir::TypeBindingKind::Equality { term: ty.into() } + }) + } + 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); + + hir::TypeBindingKind::Constraint { bounds } + } + DesugarKind::Error(position) => { + self.tcx.sess.emit_err(errors::MisplacedAssocTyBinding { + span: constraint.span, + position: DiagnosticArgFromDisplay(position), + }); + let err_ty = &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err)); + hir::TypeBindingKind::Equality { term: err_ty.into() } + } } } }; 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 2d04f6fc452..8cab1f66c27 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 @@ -8,7 +8,6 @@ fn f() where dyn for<'j> B<AssocType: 'j>:, //~^ ERROR associated type bounds are only allowed in where clauses and function signatures - //~| ERROR the value of the associated type `AssocType` (from trait `B`) must be specified { } 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 ffba044e7e7..fdc221eeda2 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 @@ -4,15 +4,5 @@ error: associated type bounds are only allowed in where clauses and function sig LL | dyn for<'j> B<AssocType: 'j>:, | ^^^^^^^^^^^^^ -error[E0191]: the value of the associated type `AssocType` (from trait `B`) must be specified - --> $DIR/bad-universal-in-dyn-in-where-clause.rs:9:9 - | -LL | type AssocType; - | -------------- `AssocType` defined here -... -LL | dyn for<'j> B<AssocType: 'j>:, - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `for<'j> B<AssocType: 'j, AssocType = Type>` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0191`. 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 dd59dbd243e..1d5d181efcc 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 @@ -9,6 +9,5 @@ trait Trait2 {} // It's not possible to insert a universal `impl Trait` here! impl dyn Trait<Item: Trait2> {} //~^ ERROR associated type bounds are only allowed in where clauses and function signatures -//~| ERROR the value of the associated type `Item` (from trait `Trait`) must be specified fn main() {} diff --git a/tests/ui/associated-type-bounds/inside-adt.rs b/tests/ui/associated-type-bounds/inside-adt.rs index 70a30287092..057966941dc 100644 --- a/tests/ui/associated-type-bounds/inside-adt.rs +++ b/tests/ui/associated-type-bounds/inside-adt.rs @@ -4,32 +4,23 @@ use std::mem::ManuallyDrop; struct S1 { f: dyn Iterator<Item: Copy> } //~^ ERROR associated type bounds are only allowed in where clauses and function signatures -//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified struct S2 { f: Box<dyn Iterator<Item: Copy>> } //~^ ERROR associated type bounds are only allowed in where clauses and function signatures -//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified struct S3 { f: dyn Iterator<Item: 'static> } //~^ ERROR associated type bounds are only allowed in where clauses and function signatures -//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified enum E1 { V(dyn Iterator<Item: Copy>) } //~^ ERROR associated type bounds are only allowed in where clauses and function signatures -//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified enum E2 { V(Box<dyn Iterator<Item: Copy>>) } //~^ ERROR associated type bounds are only allowed in where clauses and function signatures -//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified enum E3 { V(dyn Iterator<Item: 'static>) } //~^ ERROR associated type bounds are only allowed in where clauses and function signatures -//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> } //~^ ERROR associated type bounds are only allowed in where clauses and function signatures -//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> } //~^ ERROR associated type bounds are only allowed in where clauses and function signatures -//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> } //~^ ERROR associated type bounds are only allowed in where clauses and function signatures -//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified fn main() {} diff --git a/tests/ui/associated-type-bounds/inside-adt.stderr b/tests/ui/associated-type-bounds/inside-adt.stderr index e1d35bd9c32..f631ad5b78a 100644 --- a/tests/ui/associated-type-bounds/inside-adt.stderr +++ b/tests/ui/associated-type-bounds/inside-adt.stderr @@ -5,125 +5,52 @@ LL | struct S1 { f: dyn Iterator<Item: Copy> } | ^^^^^^^^^^ error: associated type bounds are only allowed in where clauses and function signatures, not in field type - --> $DIR/inside-adt.rs:8:33 + --> $DIR/inside-adt.rs:7:33 | LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> } | ^^^^^^^^^^ error: associated type bounds are only allowed in where clauses and function signatures, not in field type - --> $DIR/inside-adt.rs:11:29 + --> $DIR/inside-adt.rs:9:29 | LL | struct S3 { f: dyn Iterator<Item: 'static> } | ^^^^^^^^^^^^^ error: associated type bounds are only allowed in where clauses and function signatures, not in field type - --> $DIR/inside-adt.rs:15:26 + --> $DIR/inside-adt.rs:12:26 | LL | enum E1 { V(dyn Iterator<Item: Copy>) } | ^^^^^^^^^^ error: associated type bounds are only allowed in where clauses and function signatures, not in field type - --> $DIR/inside-adt.rs:18:30 + --> $DIR/inside-adt.rs:14:30 | LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) } | ^^^^^^^^^^ error: associated type bounds are only allowed in where clauses and function signatures, not in field type - --> $DIR/inside-adt.rs:21:26 + --> $DIR/inside-adt.rs:16:26 | LL | enum E3 { V(dyn Iterator<Item: 'static>) } | ^^^^^^^^^^^^^ error: associated type bounds are only allowed in where clauses and function signatures, not in field type - --> $DIR/inside-adt.rs:25:41 + --> $DIR/inside-adt.rs:19:41 | LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> } | ^^^^^^^^^^ error: associated type bounds are only allowed in where clauses and function signatures, not in field type - --> $DIR/inside-adt.rs:28:45 + --> $DIR/inside-adt.rs:21:45 | LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> } | ^^^^^^^^^^ error: associated type bounds are only allowed in where clauses and function signatures, not in field type - --> $DIR/inside-adt.rs:31:41 + --> $DIR/inside-adt.rs:23:41 | LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> } | ^^^^^^^^^^^^^ -error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified - --> $DIR/inside-adt.rs:5:20 - | -LL | struct S1 { f: dyn Iterator<Item: Copy> } - | ^^^^^^^^^^^^^^^^^^^^ - | | - | associated type `Item` must be specified - | help: specify the associated types: `Iterator<Item: Copy, Item = Type>` - -error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified - --> $DIR/inside-adt.rs:8:24 - | -LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> } - | ^^^^^^^^^^^^^^^^^^^^ - | | - | associated type `Item` must be specified - | help: specify the associated types: `Iterator<Item: Copy, Item = Type>` - -error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified - --> $DIR/inside-adt.rs:11:20 - | -LL | struct S3 { f: dyn Iterator<Item: 'static> } - | ^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Iterator<Item: 'static, Item = Type>` - -error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified - --> $DIR/inside-adt.rs:15:17 - | -LL | enum E1 { V(dyn Iterator<Item: Copy>) } - | ^^^^^^^^^^^^^^^^^^^^ - | | - | associated type `Item` must be specified - | help: specify the associated types: `Iterator<Item: Copy, Item = Type>` - -error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified - --> $DIR/inside-adt.rs:18:21 - | -LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) } - | ^^^^^^^^^^^^^^^^^^^^ - | | - | associated type `Item` must be specified - | help: specify the associated types: `Iterator<Item: Copy, Item = Type>` - -error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified - --> $DIR/inside-adt.rs:21:17 - | -LL | enum E3 { V(dyn Iterator<Item: 'static>) } - | ^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Iterator<Item: 'static, Item = Type>` - -error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified - --> $DIR/inside-adt.rs:25:32 - | -LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> } - | ^^^^^^^^^^^^^^^^^^^^ - | | - | associated type `Item` must be specified - | help: specify the associated types: `Iterator<Item: Copy, Item = Type>` - -error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified - --> $DIR/inside-adt.rs:28:36 - | -LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> } - | ^^^^^^^^^^^^^^^^^^^^ - | | - | associated type `Item` must be specified - | help: specify the associated types: `Iterator<Item: Copy, Item = Type>` - -error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified - --> $DIR/inside-adt.rs:31:32 - | -LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> } - | ^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Iterator<Item: 'static, Item = Type>` - -error: aborting due to 18 previous errors +error: aborting due to 9 previous errors -For more information about this error, try `rustc --explain E0191`. |
