Skip to content

Commit c02b3c7

Browse files
author
Lukas Markeffsky
committed
suppress errors about T: !Thin caused by T: !Sized
1 parent a7f12dc commit c02b3c7

File tree

7 files changed

+84
-229
lines changed

7 files changed

+84
-229
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
103103
};
104104

105105
#[derive(Debug)]
106-
struct ErrorDescriptor<'tcx> {
106+
struct ErrorDescriptor<'tcx, 'err> {
107107
predicate: ty::Predicate<'tcx>,
108-
index: Option<usize>, // None if this is an old error
108+
source: Option<(usize, &'err FulfillmentError<'tcx>)>, // None if this is an old error
109109
}
110110

111111
let mut error_map: FxIndexMap<_, Vec<_>> = self
@@ -117,7 +117,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
117117
let span = strip_desugaring(span);
118118
let reported_errors = predicates
119119
.iter()
120-
.map(|&predicate| ErrorDescriptor { predicate, index: None })
120+
.map(|&predicate| ErrorDescriptor { predicate, source: None })
121121
.collect();
122122
(span, reported_errors)
123123
})
@@ -154,7 +154,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
154154
let span = strip_desugaring(error.obligation.cause.span);
155155
error_map.entry(span).or_default().push(ErrorDescriptor {
156156
predicate: error.obligation.predicate,
157-
index: Some(index),
157+
source: Some((index, error)),
158158
});
159159
}
160160

@@ -164,22 +164,37 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
164164
for (_, error_set) in error_map.iter() {
165165
// We want to suppress "duplicate" errors with the same span.
166166
for error in error_set {
167-
let Some(index) = error.index else {
167+
let Some((index, error_source)) = error.source else {
168168
continue;
169169
};
170170

171-
// Suppress errors that are either:
172-
// 1) strictly implied by another error.
173-
// 2) implied by an error with a smaller index.
174171
for error2 in error_set {
175-
if self.error_implies(error2.predicate, error.predicate)
176-
&& (!error2.index.is_some_and(|index2| index2 >= index)
177-
|| !self.error_implies(error.predicate, error2.predicate))
172+
// Suppress errors that are either:
173+
// 1) strictly implied by another error.
174+
// 2) implied by an error with a smaller index.
175+
if self.error_implied_by(error.predicate, error2.predicate)
176+
&& (!error2.source.is_some_and(|(index2, _)| index2 >= index)
177+
|| !self.error_implied_by(error2.predicate, error.predicate))
178178
{
179179
info!("skipping `{}` (implied by `{}`)", error.predicate, error2.predicate);
180180
is_suppressed[index] = true;
181181
break;
182182
}
183+
184+
// Also suppress the error if we are absolutely certain that a different
185+
// error is the one that the user should fix. This will suppress errors
186+
// about `<T as Pointee>::Metadata == ()` that can be fixed by `T: Sized`.
187+
if error.predicate.to_opt_poly_projection_pred().is_some()
188+
&& error2.predicate.to_opt_poly_trait_pred().is_some()
189+
&& self.error_fixed_by(
190+
error_source.obligation.clone(),
191+
error2.predicate.expect_clause(),
192+
)
193+
{
194+
info!("skipping `{}` (fixed by `{}`)", error.predicate, error2.predicate);
195+
is_suppressed[index] = true;
196+
break;
197+
}
183198
}
184199
}
185200
}
@@ -1474,10 +1489,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
14741489
&& self.can_eq(param_env, goal.term, assumption.term)
14751490
}
14761491

1477-
// returns if `cond` not occurring implies that `error` does not occur - i.e., that
1478-
// `error` occurring implies that `cond` occurs.
1492+
/// Returns whether `cond` not occurring implies that `error` does not occur - i.e., that
1493+
/// `error` occurring implies that `cond` occurs.
14791494
#[instrument(level = "debug", skip(self), ret)]
1480-
fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool {
1495+
fn error_implied_by(&self, error: ty::Predicate<'tcx>, cond: ty::Predicate<'tcx>) -> bool {
14811496
if cond == error {
14821497
return true;
14831498
}
@@ -1499,6 +1514,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
14991514
}
15001515
}
15011516

1517+
/// Returns whether fixing `cond` will also fix `error`.
1518+
#[instrument(level = "debug", skip(self), ret)]
1519+
fn error_fixed_by(&self, mut error: PredicateObligation<'tcx>, cond: ty::Clause<'tcx>) -> bool {
1520+
self.probe(|_| {
1521+
let ocx = ObligationCtxt::new(self);
1522+
1523+
let clauses = elaborate(self.tcx, std::iter::once(cond)).collect::<Vec<_>>();
1524+
let clauses = ocx.normalize(&error.cause, error.param_env, clauses);
1525+
let mut clauses = self.resolve_vars_if_possible(clauses);
1526+
1527+
if clauses.has_infer() {
1528+
return false;
1529+
}
1530+
1531+
clauses.extend(error.param_env.caller_bounds());
1532+
let clauses = self.tcx.mk_clauses(&clauses);
1533+
error.param_env = ty::ParamEnv::new(clauses, error.param_env.reveal());
1534+
1535+
ocx.register_obligation(error);
1536+
ocx.select_all_or_error().is_empty()
1537+
})
1538+
}
1539+
15021540
#[instrument(skip(self), level = "debug")]
15031541
fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed {
15041542
if self.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default()

tests/ui/feature-gates/feature-gate-trivial_bounds.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ struct TwoStrs(str, str) where str: Sized; //~ ERROR
5353

5454

5555
fn unsized_local() where Dst<dyn A>: Sized { //~ ERROR
56-
//~^ ERROR type mismatch resolving `<Dst<dyn A> as Pointee>::Metadata == ()`
5756
let x: Dst<dyn A> = *(Box::new(Dst { x: 1 }) as Box<Dst<dyn A>>);
5857
}
5958

tests/ui/feature-gates/feature-gate-trivial_bounds.stderr

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -132,20 +132,8 @@ help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
132132
LL + #![feature(trivial_bounds)]
133133
|
134134

135-
error[E0271]: type mismatch resolving `<Dst<dyn A> as Pointee>::Metadata == ()`
136-
--> $DIR/feature-gate-trivial_bounds.rs:55:26
137-
|
138-
LL | fn unsized_local() where Dst<dyn A>: Sized {
139-
| ^^^^^^^^^^^^^^^^^ expected `DynMetadata<(dyn A + 'static)>`, found `()`
140-
|
141-
= help: see issue #48214
142-
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
143-
|
144-
LL + #![feature(trivial_bounds)]
145-
|
146-
147135
error[E0277]: the size for values of type `str` cannot be known at compilation time
148-
--> $DIR/feature-gate-trivial_bounds.rs:60:30
136+
--> $DIR/feature-gate-trivial_bounds.rs:59:30
149137
|
150138
LL | fn return_str() -> str where str: Sized {
151139
| ^^^^^^^^^^ doesn't have a size known at compile-time
@@ -157,7 +145,6 @@ help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
157145
LL + #![feature(trivial_bounds)]
158146
|
159147

160-
error: aborting due to 12 previous errors
148+
error: aborting due to 11 previous errors
161149

162-
Some errors have detailed explanations: E0271, E0277.
163-
For more information about an error, try `rustc --explain E0271`.
150+
For more information about this error, try `rustc --explain E0277`.

tests/ui/trait-bounds/super-assoc-mismatch.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,27 +45,22 @@ impl<T: Sub> Sub for Wrapper<T> {}
4545

4646
impl BoundOnSelf for Wrapper<()> {}
4747
//~^ ERROR the trait bound `(): Sub` is not satisfied
48-
//~| ERROR type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16
4948

5049
impl BoundOnParam<Wrapper<()>> for Wrapper<()> {}
5150
//~^ ERROR the trait bound `(): Sub` is not satisfied
52-
//~| ERROR type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16
5351

5452
impl BoundOnAssoc for Wrapper<()> {
5553
type Assoc = Wrapper<()>;
5654
//~^ ERROR the trait bound `(): Sub` is not satisfied
57-
//~| ERROR type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16
5855
}
5956

6057
impl BoundOnGat for Wrapper<()> {
6158
type Assoc<T> = Wrapper<()>;
6259
//~^ ERROR the trait bound `(): Sub` is not satisfied
63-
//~| ERROR type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16
6460
}
6561

6662
fn trivial_bound_wrapper() where Wrapper<()>: Sub {}
6763
//~^ ERROR the trait bound `(): Sub` is not satisfied
68-
//~| ERROR type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16
6964

7065
// The following is an edge case where the unsatisfied projection predicate
7166
// `<<u8 as MultiAssoc>::Assoc1<()> as SuperGeneric<u16>>::Assoc == <u8 as MultiAssoc>::Assoc2`

tests/ui/trait-bounds/super-assoc-mismatch.stderr

Lines changed: 9 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -63,28 +63,6 @@ help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
6363
LL + #![feature(trivial_bounds)]
6464
|
6565

66-
error[E0271]: type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
67-
--> $DIR/super-assoc-mismatch.rs:46:22
68-
|
69-
LL | impl BoundOnSelf for Wrapper<()> {}
70-
| ^^^^^^^^^^^ type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
71-
|
72-
note: expected this to be `u16`
73-
--> $DIR/super-assoc-mismatch.rs:42:18
74-
|
75-
LL | type Assoc = T::Assoc;
76-
| ^^^^^^^^
77-
note: required for `Wrapper<()>` to implement `Sub`
78-
--> $DIR/super-assoc-mismatch.rs:7:7
79-
|
80-
LL | trait Sub: Super<Assoc = u16> {}
81-
| ^^^
82-
note: required by a bound in `BoundOnSelf`
83-
--> $DIR/super-assoc-mismatch.rs:11:20
84-
|
85-
LL | trait BoundOnSelf: Sub {}
86-
| ^^^ required by this bound in `BoundOnSelf`
87-
8866
error[E0277]: the trait bound `(): Sub` is not satisfied
8967
--> $DIR/super-assoc-mismatch.rs:46:22
9068
|
@@ -105,30 +83,8 @@ note: required by a bound in `BoundOnSelf`
10583
LL | trait BoundOnSelf: Sub {}
10684
| ^^^ required by this bound in `BoundOnSelf`
10785

108-
error[E0271]: type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
109-
--> $DIR/super-assoc-mismatch.rs:50:36
110-
|
111-
LL | impl BoundOnParam<Wrapper<()>> for Wrapper<()> {}
112-
| ^^^^^^^^^^^ type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
113-
|
114-
note: expected this to be `u16`
115-
--> $DIR/super-assoc-mismatch.rs:42:18
116-
|
117-
LL | type Assoc = T::Assoc;
118-
| ^^^^^^^^
119-
note: required for `Wrapper<()>` to implement `Sub`
120-
--> $DIR/super-assoc-mismatch.rs:7:7
121-
|
122-
LL | trait Sub: Super<Assoc = u16> {}
123-
| ^^^
124-
note: required by a bound in `BoundOnParam`
125-
--> $DIR/super-assoc-mismatch.rs:15:23
126-
|
127-
LL | trait BoundOnParam<T: Sub> {}
128-
| ^^^ required by this bound in `BoundOnParam`
129-
13086
error[E0277]: the trait bound `(): Sub` is not satisfied
131-
--> $DIR/super-assoc-mismatch.rs:50:36
87+
--> $DIR/super-assoc-mismatch.rs:49:36
13288
|
13389
LL | impl BoundOnParam<Wrapper<()>> for Wrapper<()> {}
13490
| ^^^^^^^^^^^ the trait `Sub` is not implemented for `()`, which is required by `Wrapper<()>: Sub`
@@ -147,30 +103,8 @@ note: required by a bound in `BoundOnParam`
147103
LL | trait BoundOnParam<T: Sub> {}
148104
| ^^^ required by this bound in `BoundOnParam`
149105

150-
error[E0271]: type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
151-
--> $DIR/super-assoc-mismatch.rs:55:18
152-
|
153-
LL | type Assoc = Wrapper<()>;
154-
| ^^^^^^^^^^^ type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
155-
|
156-
note: expected this to be `u16`
157-
--> $DIR/super-assoc-mismatch.rs:42:18
158-
|
159-
LL | type Assoc = T::Assoc;
160-
| ^^^^^^^^
161-
note: required for `<Wrapper<()> as BoundOnAssoc>::Assoc` to implement `Sub`
162-
--> $DIR/super-assoc-mismatch.rs:7:7
163-
|
164-
LL | trait Sub: Super<Assoc = u16> {}
165-
| ^^^
166-
note: required by a bound in `BoundOnAssoc::Assoc`
167-
--> $DIR/super-assoc-mismatch.rs:20:17
168-
|
169-
LL | type Assoc: Sub;
170-
| ^^^ required by this bound in `BoundOnAssoc::Assoc`
171-
172106
error[E0277]: the trait bound `(): Sub` is not satisfied
173-
--> $DIR/super-assoc-mismatch.rs:55:18
107+
--> $DIR/super-assoc-mismatch.rs:53:18
174108
|
175109
LL | type Assoc = Wrapper<()>;
176110
| ^^^^^^^^^^^ the trait `Sub` is not implemented for `()`, which is required by `Wrapper<()>: Sub`
@@ -189,30 +123,8 @@ note: required by a bound in `BoundOnAssoc::Assoc`
189123
LL | type Assoc: Sub;
190124
| ^^^ required by this bound in `BoundOnAssoc::Assoc`
191125

192-
error[E0271]: type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
193-
--> $DIR/super-assoc-mismatch.rs:61:21
194-
|
195-
LL | type Assoc<T> = Wrapper<()>;
196-
| ^^^^^^^^^^^ type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
197-
|
198-
note: expected this to be `u16`
199-
--> $DIR/super-assoc-mismatch.rs:42:18
200-
|
201-
LL | type Assoc = T::Assoc;
202-
| ^^^^^^^^
203-
note: required for `<Wrapper<()> as BoundOnGat>::Assoc<u8>` to implement `Sub`
204-
--> $DIR/super-assoc-mismatch.rs:7:7
205-
|
206-
LL | trait Sub: Super<Assoc = u16> {}
207-
| ^^^
208-
note: required by a bound in `BoundOnGat`
209-
--> $DIR/super-assoc-mismatch.rs:27:41
210-
|
211-
LL | trait BoundOnGat where Self::Assoc<u8>: Sub {
212-
| ^^^ required by this bound in `BoundOnGat`
213-
214126
error[E0277]: the trait bound `(): Sub` is not satisfied
215-
--> $DIR/super-assoc-mismatch.rs:61:21
127+
--> $DIR/super-assoc-mismatch.rs:58:21
216128
|
217129
LL | type Assoc<T> = Wrapper<()>;
218130
| ^^^^^^^^^^^ the trait `Sub` is not implemented for `()`, which is required by `<Wrapper<()> as BoundOnGat>::Assoc<u8>: Sub`
@@ -231,25 +143,8 @@ note: required by a bound in `BoundOnGat`
231143
LL | trait BoundOnGat where Self::Assoc<u8>: Sub {
232144
| ^^^ required by this bound in `BoundOnGat`
233145

234-
error[E0271]: type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
235-
--> $DIR/super-assoc-mismatch.rs:66:34
236-
|
237-
LL | fn trivial_bound_wrapper() where Wrapper<()>: Sub {}
238-
| ^^^^^^^^^^^^^^^^ type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
239-
|
240-
note: expected this to be `u8`
241-
--> $DIR/super-assoc-mismatch.rs:42:18
242-
|
243-
LL | type Assoc = T::Assoc;
244-
| ^^^^^^^^
245-
= help: see issue #48214
246-
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
247-
|
248-
LL + #![feature(trivial_bounds)]
249-
|
250-
251146
error[E0277]: the trait bound `(): Sub` is not satisfied
252-
--> $DIR/super-assoc-mismatch.rs:66:34
147+
--> $DIR/super-assoc-mismatch.rs:62:34
253148
|
254149
LL | fn trivial_bound_wrapper() where Wrapper<()>: Sub {}
255150
| ^^^^^^^^^^^^^^^^ the trait `Sub` is not implemented for `()`, which is required by `Wrapper<()>: Sub`
@@ -269,26 +164,25 @@ LL + #![feature(trivial_bounds)]
269164
|
270165

271166
error[E0277]: the trait bound `(): SubGeneric<u16>` is not satisfied
272-
--> $DIR/super-assoc-mismatch.rs:89:22
167+
--> $DIR/super-assoc-mismatch.rs:84:22
273168
|
274169
LL | type Assoc1<T> = ();
275170
| ^^ the trait `SubGeneric<u16>` is not implemented for `()`, which is required by `<u8 as MultiAssoc>::Assoc1<()>: SubGeneric<<u8 as MultiAssoc>::Assoc2>`
276171
|
277172
help: this trait has no implementations, consider adding one
278-
--> $DIR/super-assoc-mismatch.rs:77:1
173+
--> $DIR/super-assoc-mismatch.rs:72:1
279174
|
280175
LL | trait SubGeneric<T>: SuperGeneric<T, Assoc = T> {}
281176
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
282177
note: required by a bound in `MultiAssoc`
283-
--> $DIR/super-assoc-mismatch.rs:80:23
178+
--> $DIR/super-assoc-mismatch.rs:75:23
284179
|
285180
LL | trait MultiAssoc
286181
| ---------- required by a bound in this trait
287182
LL | where
288183
LL | Self::Assoc1<()>: SubGeneric<Self::Assoc2>
289184
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `MultiAssoc`
290185

291-
error: aborting due to 16 previous errors
186+
error: aborting due to 11 previous errors
292187

293-
Some errors have detailed explanations: E0271, E0277.
294-
For more information about an error, try `rustc --explain E0271`.
188+
For more information about this error, try `rustc --explain E0277`.

tests/ui/trait-bounds/unsized-bound.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,14 @@ trait Trait<A> {}
22
impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
33
//~^ ERROR E0277
44
//~| ERROR E0277
5-
//~| ERROR type mismatch resolving `<(A, B) as Pointee>::Metadata == ()` [E0271]
65
impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
76
//~^ ERROR E0277
87
//~| ERROR E0277
98
//~| ERROR E0277
10-
//~| ERROR type mismatch resolving `<(A, B, C) as Pointee>::Metadata == ()` [E0271]
119
trait Trait2<A> {}
1210
impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
1311
//~^ ERROR E0277
1412
//~| ERROR E0277
15-
//~| ERROR type mismatch resolving `<(A, B) as Pointee>::Metadata == ()` [E0271]
1613
trait Trait3<A> {}
1714
impl<A> Trait3<A> for A where A: ?Sized {}
1815
//~^ ERROR E0277

0 commit comments

Comments
 (0)