Skip to content

Commit deb1357

Browse files
Suppress duplicated errors for associated type bounds in object types
1 parent e7c4908 commit deb1357

File tree

6 files changed

+56
-137
lines changed

6 files changed

+56
-137
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+46-33
Original file line numberDiff line numberDiff line change
@@ -1011,8 +1011,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10111011
hir::TypeBindingKind::Equality { term }
10121012
}
10131013
AssocConstraintKind::Bound { bounds } => {
1014+
enum DesugarKind<'a> {
1015+
ImplTrait,
1016+
Error(&'a ImplTraitPosition),
1017+
Bound,
1018+
}
1019+
10141020
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
1015-
let (desugar_to_impl_trait, itctx) = match itctx {
1021+
let desugar_kind = match itctx {
10161022
// We are in the return position:
10171023
//
10181024
// fn foo() -> impl Iterator<Item: Debug>
@@ -1021,7 +1027,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10211027
//
10221028
// fn foo() -> impl Iterator<Item = impl Debug>
10231029
ImplTraitContext::ReturnPositionOpaqueTy { .. }
1024-
| ImplTraitContext::TypeAliasesOpaqueTy { .. } => (true, itctx),
1030+
| ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait,
10251031

10261032
// We are in the argument position, but within a dyn type:
10271033
//
@@ -1030,7 +1036,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10301036
// so desugar to
10311037
//
10321038
// fn foo(x: dyn Iterator<Item = impl Debug>)
1033-
ImplTraitContext::Universal if self.is_in_dyn_type => (true, itctx),
1039+
ImplTraitContext::Universal if self.is_in_dyn_type => DesugarKind::ImplTrait,
10341040

10351041
// In `type Foo = dyn Iterator<Item: Debug>` we desugar to
10361042
// `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
@@ -1039,11 +1045,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10391045
//
10401046
// FIXME: this is only needed until `impl Trait` is allowed in type aliases.
10411047
ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => {
1042-
self.tcx.sess.emit_err(errors::MisplacedAssocTyBinding {
1043-
span: constraint.span,
1044-
position: DiagnosticArgFromDisplay(position),
1045-
});
1046-
(false, itctx)
1048+
DesugarKind::Error(position)
10471049
}
10481050

10491051
// We are in the parameter position, but not within a dyn type:
@@ -1053,35 +1055,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10531055
// so we leave it as is and this gets expanded in astconv to a bound like
10541056
// `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
10551057
// `impl Iterator`.
1056-
_ => (false, itctx),
1058+
_ => DesugarKind::Bound,
10571059
};
10581060

1059-
if desugar_to_impl_trait {
1060-
// Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
1061-
// constructing the HIR for `impl bounds...` and then lowering that.
1062-
1063-
let impl_trait_node_id = self.next_node_id();
1064-
1065-
self.with_dyn_type_scope(false, |this| {
1066-
let node_id = this.next_node_id();
1067-
let ty = this.lower_ty(
1068-
&Ty {
1069-
id: node_id,
1070-
kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
1071-
span: this.lower_span(constraint.span),
1072-
tokens: None,
1073-
},
1074-
itctx,
1075-
);
1061+
match desugar_kind {
1062+
DesugarKind::ImplTrait => {
1063+
// Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
1064+
// constructing the HIR for `impl bounds...` and then lowering that.
10761065

1077-
hir::TypeBindingKind::Equality { term: ty.into() }
1078-
})
1079-
} else {
1080-
// Desugar `AssocTy: Bounds` into a type binding where the
1081-
// later desugars into a trait predicate.
1082-
let bounds = self.lower_param_bounds(bounds, itctx);
1066+
let impl_trait_node_id = self.next_node_id();
1067+
1068+
self.with_dyn_type_scope(false, |this| {
1069+
let node_id = this.next_node_id();
1070+
let ty = this.lower_ty(
1071+
&Ty {
1072+
id: node_id,
1073+
kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
1074+
span: this.lower_span(constraint.span),
1075+
tokens: None,
1076+
},
1077+
itctx,
1078+
);
10831079

1084-
hir::TypeBindingKind::Constraint { bounds }
1080+
hir::TypeBindingKind::Equality { term: ty.into() }
1081+
})
1082+
}
1083+
DesugarKind::Bound => {
1084+
// Desugar `AssocTy: Bounds` into a type binding where the
1085+
// later desugars into a trait predicate.
1086+
let bounds = self.lower_param_bounds(bounds, itctx);
1087+
1088+
hir::TypeBindingKind::Constraint { bounds }
1089+
}
1090+
DesugarKind::Error(position) => {
1091+
self.tcx.sess.emit_err(errors::MisplacedAssocTyBinding {
1092+
span: constraint.span,
1093+
position: DiagnosticArgFromDisplay(position),
1094+
});
1095+
let err_ty = &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err));
1096+
hir::TypeBindingKind::Equality { term: err_ty.into() }
1097+
}
10851098
}
10861099
}
10871100
};

tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ fn f()
88
where
99
dyn for<'j> B<AssocType: 'j>:,
1010
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
11-
//~| ERROR the value of the associated type `AssocType` (from trait `B`) must be specified
1211
{
1312
}
1413

tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr

+1-11
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,5 @@ error: associated type bounds are only allowed in where clauses and function sig
44
LL | dyn for<'j> B<AssocType: 'j>:,
55
| ^^^^^^^^^^^^^
66

7-
error[E0191]: the value of the associated type `AssocType` (from trait `B`) must be specified
8-
--> $DIR/bad-universal-in-dyn-in-where-clause.rs:9:9
9-
|
10-
LL | type AssocType;
11-
| -------------- `AssocType` defined here
12-
...
13-
LL | dyn for<'j> B<AssocType: 'j>:,
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `for<'j> B<AssocType: 'j, AssocType = Type>`
15-
16-
error: aborting due to 2 previous errors
7+
error: aborting due to previous error
178

18-
For more information about this error, try `rustc --explain E0191`.

tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs

-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,5 @@ trait Trait2 {}
99
// It's not possible to insert a universal `impl Trait` here!
1010
impl dyn Trait<Item: Trait2> {}
1111
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
12-
//~| ERROR the value of the associated type `Item` (from trait `Trait`) must be specified
1312

1413
fn main() {}

tests/ui/associated-type-bounds/inside-adt.rs

-9
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,23 @@ use std::mem::ManuallyDrop;
44

55
struct S1 { f: dyn Iterator<Item: Copy> }
66
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
7-
//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
87
struct S2 { f: Box<dyn Iterator<Item: Copy>> }
98
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
10-
//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
119
struct S3 { f: dyn Iterator<Item: 'static> }
1210
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
13-
//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
1411

1512
enum E1 { V(dyn Iterator<Item: Copy>) }
1613
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
17-
//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
1814
enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
1915
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
20-
//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
2116
enum E3 { V(dyn Iterator<Item: 'static>) }
2217
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
23-
//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
2418

2519
union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
2620
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
27-
//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
2821
union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
2922
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
30-
//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
3123
union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
3224
//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
33-
//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
3425

3526
fn main() {}

tests/ui/associated-type-bounds/inside-adt.stderr

+9-82
Original file line numberDiff line numberDiff line change
@@ -5,125 +5,52 @@ LL | struct S1 { f: dyn Iterator<Item: Copy> }
55
| ^^^^^^^^^^
66

77
error: associated type bounds are only allowed in where clauses and function signatures, not in field type
8-
--> $DIR/inside-adt.rs:8:33
8+
--> $DIR/inside-adt.rs:7:33
99
|
1010
LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> }
1111
| ^^^^^^^^^^
1212

1313
error: associated type bounds are only allowed in where clauses and function signatures, not in field type
14-
--> $DIR/inside-adt.rs:11:29
14+
--> $DIR/inside-adt.rs:9:29
1515
|
1616
LL | struct S3 { f: dyn Iterator<Item: 'static> }
1717
| ^^^^^^^^^^^^^
1818

1919
error: associated type bounds are only allowed in where clauses and function signatures, not in field type
20-
--> $DIR/inside-adt.rs:15:26
20+
--> $DIR/inside-adt.rs:12:26
2121
|
2222
LL | enum E1 { V(dyn Iterator<Item: Copy>) }
2323
| ^^^^^^^^^^
2424

2525
error: associated type bounds are only allowed in where clauses and function signatures, not in field type
26-
--> $DIR/inside-adt.rs:18:30
26+
--> $DIR/inside-adt.rs:14:30
2727
|
2828
LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
2929
| ^^^^^^^^^^
3030

3131
error: associated type bounds are only allowed in where clauses and function signatures, not in field type
32-
--> $DIR/inside-adt.rs:21:26
32+
--> $DIR/inside-adt.rs:16:26
3333
|
3434
LL | enum E3 { V(dyn Iterator<Item: 'static>) }
3535
| ^^^^^^^^^^^^^
3636

3737
error: associated type bounds are only allowed in where clauses and function signatures, not in field type
38-
--> $DIR/inside-adt.rs:25:41
38+
--> $DIR/inside-adt.rs:19:41
3939
|
4040
LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
4141
| ^^^^^^^^^^
4242

4343
error: associated type bounds are only allowed in where clauses and function signatures, not in field type
44-
--> $DIR/inside-adt.rs:28:45
44+
--> $DIR/inside-adt.rs:21:45
4545
|
4646
LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
4747
| ^^^^^^^^^^
4848

4949
error: associated type bounds are only allowed in where clauses and function signatures, not in field type
50-
--> $DIR/inside-adt.rs:31:41
50+
--> $DIR/inside-adt.rs:23:41
5151
|
5252
LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
5353
| ^^^^^^^^^^^^^
5454

55-
error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
56-
--> $DIR/inside-adt.rs:5:20
57-
|
58-
LL | struct S1 { f: dyn Iterator<Item: Copy> }
59-
| ^^^^^^^^^^^^^^^^^^^^
60-
| |
61-
| associated type `Item` must be specified
62-
| help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
63-
64-
error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
65-
--> $DIR/inside-adt.rs:8:24
66-
|
67-
LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> }
68-
| ^^^^^^^^^^^^^^^^^^^^
69-
| |
70-
| associated type `Item` must be specified
71-
| help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
72-
73-
error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
74-
--> $DIR/inside-adt.rs:11:20
75-
|
76-
LL | struct S3 { f: dyn Iterator<Item: 'static> }
77-
| ^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Iterator<Item: 'static, Item = Type>`
78-
79-
error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
80-
--> $DIR/inside-adt.rs:15:17
81-
|
82-
LL | enum E1 { V(dyn Iterator<Item: Copy>) }
83-
| ^^^^^^^^^^^^^^^^^^^^
84-
| |
85-
| associated type `Item` must be specified
86-
| help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
87-
88-
error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
89-
--> $DIR/inside-adt.rs:18:21
90-
|
91-
LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
92-
| ^^^^^^^^^^^^^^^^^^^^
93-
| |
94-
| associated type `Item` must be specified
95-
| help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
96-
97-
error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
98-
--> $DIR/inside-adt.rs:21:17
99-
|
100-
LL | enum E3 { V(dyn Iterator<Item: 'static>) }
101-
| ^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Iterator<Item: 'static, Item = Type>`
102-
103-
error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
104-
--> $DIR/inside-adt.rs:25:32
105-
|
106-
LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
107-
| ^^^^^^^^^^^^^^^^^^^^
108-
| |
109-
| associated type `Item` must be specified
110-
| help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
111-
112-
error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
113-
--> $DIR/inside-adt.rs:28:36
114-
|
115-
LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
116-
| ^^^^^^^^^^^^^^^^^^^^
117-
| |
118-
| associated type `Item` must be specified
119-
| help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
120-
121-
error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
122-
--> $DIR/inside-adt.rs:31:32
123-
|
124-
LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
125-
| ^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Iterator<Item: 'static, Item = Type>`
126-
127-
error: aborting due to 18 previous errors
55+
error: aborting due to 9 previous errors
12856

129-
For more information about this error, try `rustc --explain E0191`.

0 commit comments

Comments
 (0)