Suppress duplicated errors for associated type bounds in object types

This commit is contained in:
Michael Goulet 2023-02-14 20:07:33 +00:00
parent e7c490892f
commit deb135748d
6 changed files with 54 additions and 135 deletions

View File

@ -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.
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();
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,
);
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() }
})
} 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::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 }
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() }
}
}
}
};

View File

@ -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
{
}

View File

@ -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 previous error
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0191`.

View File

@ -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() {}

View File

@ -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() {}

View File

@ -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: aborting due to 9 previous errors
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
For more information about this error, try `rustc --explain E0191`.