Skip to content

Commit c0c2feb

Browse files
author
Lukas Markeffsky
committed
suppress errors about T: !Thin caused by T: !Sized
1 parent 56227e6 commit c0c2feb

File tree

7 files changed

+84
-223
lines changed

7 files changed

+84
-223
lines changed

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

+52-14
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

-1
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

+3-13
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,8 @@ LL | struct Dst<X: ?Sized> {
102102
= help: see issue #48214
103103
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
104104

105-
error[E0271]: type mismatch resolving `<Dst<dyn A> as Pointee>::Metadata == ()`
106-
--> $DIR/feature-gate-trivial_bounds.rs:55:26
107-
|
108-
LL | fn unsized_local() where Dst<dyn A>: Sized {
109-
| ^^^^^^^^^^^^^^^^^ expected `DynMetadata<(dyn A + 'static)>`, found `()`
110-
|
111-
= help: see issue #48214
112-
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
113-
114105
error[E0277]: the size for values of type `str` cannot be known at compilation time
115-
--> $DIR/feature-gate-trivial_bounds.rs:60:30
106+
--> $DIR/feature-gate-trivial_bounds.rs:59:30
116107
|
117108
LL | fn return_str() -> str where str: Sized {
118109
| ^^^^^^^^^^ doesn't have a size known at compile-time
@@ -121,7 +112,6 @@ LL | fn return_str() -> str where str: Sized {
121112
= help: see issue #48214
122113
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
123114

124-
error: aborting due to 12 previous errors
115+
error: aborting due to 11 previous errors
125116

126-
Some errors have detailed explanations: E0271, E0277.
127-
For more information about an error, try `rustc --explain E0271`.
117+
For more information about this error, try `rustc --explain E0277`.

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

-5
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

+9-112
Original file line numberDiff line numberDiff line change
@@ -60,28 +60,6 @@ LL | fn trivial_bound() where (): Sub {}
6060
= help: see issue #48214
6161
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
6262

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

105-
error[E0271]: type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
106-
--> $DIR/super-assoc-mismatch.rs:50:36
107-
|
108-
LL | impl BoundOnParam<Wrapper<()>> for Wrapper<()> {}
109-
| ^^^^^^^^^^^ type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
110-
|
111-
note: expected this to be `u16`
112-
--> $DIR/super-assoc-mismatch.rs:42:18
113-
|
114-
LL | type Assoc = T::Assoc;
115-
| ^^^^^^^^
116-
note: required for `Wrapper<()>` to implement `Sub`
117-
--> $DIR/super-assoc-mismatch.rs:7:7
118-
|
119-
LL | trait Sub: Super<Assoc = u16> {}
120-
| ^^^
121-
note: required by a bound in `BoundOnParam`
122-
--> $DIR/super-assoc-mismatch.rs:15:23
123-
|
124-
LL | trait BoundOnParam<T: Sub> {}
125-
| ^^^ required by this bound in `BoundOnParam`
126-
12783
error[E0277]: the trait bound `(): Sub` is not satisfied
128-
--> $DIR/super-assoc-mismatch.rs:50:36
84+
--> $DIR/super-assoc-mismatch.rs:49:36
12985
|
13086
LL | impl BoundOnParam<Wrapper<()>> for Wrapper<()> {}
13187
| ^^^^^^^^^^^ the trait `Sub` is not implemented for `()`, which is required by `Wrapper<()>: Sub`
@@ -144,30 +100,8 @@ note: required by a bound in `BoundOnParam`
144100
LL | trait BoundOnParam<T: Sub> {}
145101
| ^^^ required by this bound in `BoundOnParam`
146102

147-
error[E0271]: type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
148-
--> $DIR/super-assoc-mismatch.rs:55:18
149-
|
150-
LL | type Assoc = Wrapper<()>;
151-
| ^^^^^^^^^^^ type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
152-
|
153-
note: expected this to be `u16`
154-
--> $DIR/super-assoc-mismatch.rs:42:18
155-
|
156-
LL | type Assoc = T::Assoc;
157-
| ^^^^^^^^
158-
note: required for `<Wrapper<()> as BoundOnAssoc>::Assoc` to implement `Sub`
159-
--> $DIR/super-assoc-mismatch.rs:7:7
160-
|
161-
LL | trait Sub: Super<Assoc = u16> {}
162-
| ^^^
163-
note: required by a bound in `BoundOnAssoc::Assoc`
164-
--> $DIR/super-assoc-mismatch.rs:20:17
165-
|
166-
LL | type Assoc: Sub;
167-
| ^^^ required by this bound in `BoundOnAssoc::Assoc`
168-
169103
error[E0277]: the trait bound `(): Sub` is not satisfied
170-
--> $DIR/super-assoc-mismatch.rs:55:18
104+
--> $DIR/super-assoc-mismatch.rs:53:18
171105
|
172106
LL | type Assoc = Wrapper<()>;
173107
| ^^^^^^^^^^^ the trait `Sub` is not implemented for `()`, which is required by `Wrapper<()>: Sub`
@@ -186,30 +120,8 @@ note: required by a bound in `BoundOnAssoc::Assoc`
186120
LL | type Assoc: Sub;
187121
| ^^^ required by this bound in `BoundOnAssoc::Assoc`
188122

189-
error[E0271]: type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
190-
--> $DIR/super-assoc-mismatch.rs:61:21
191-
|
192-
LL | type Assoc<T> = Wrapper<()>;
193-
| ^^^^^^^^^^^ type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
194-
|
195-
note: expected this to be `u16`
196-
--> $DIR/super-assoc-mismatch.rs:42:18
197-
|
198-
LL | type Assoc = T::Assoc;
199-
| ^^^^^^^^
200-
note: required for `<Wrapper<()> as BoundOnGat>::Assoc<u8>` to implement `Sub`
201-
--> $DIR/super-assoc-mismatch.rs:7:7
202-
|
203-
LL | trait Sub: Super<Assoc = u16> {}
204-
| ^^^
205-
note: required by a bound in `BoundOnGat`
206-
--> $DIR/super-assoc-mismatch.rs:27:41
207-
|
208-
LL | trait BoundOnGat where Self::Assoc<u8>: Sub {
209-
| ^^^ required by this bound in `BoundOnGat`
210-
211123
error[E0277]: the trait bound `(): Sub` is not satisfied
212-
--> $DIR/super-assoc-mismatch.rs:61:21
124+
--> $DIR/super-assoc-mismatch.rs:58:21
213125
|
214126
LL | type Assoc<T> = Wrapper<()>;
215127
| ^^^^^^^^^^^ the trait `Sub` is not implemented for `()`, which is required by `<Wrapper<()> as BoundOnGat>::Assoc<u8>: Sub`
@@ -228,22 +140,8 @@ note: required by a bound in `BoundOnGat`
228140
LL | trait BoundOnGat where Self::Assoc<u8>: Sub {
229141
| ^^^ required by this bound in `BoundOnGat`
230142

231-
error[E0271]: type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
232-
--> $DIR/super-assoc-mismatch.rs:66:34
233-
|
234-
LL | fn trivial_bound_wrapper() where Wrapper<()>: Sub {}
235-
| ^^^^^^^^^^^^^^^^ type mismatch resolving `<Wrapper<()> as Super>::Assoc == u16`
236-
|
237-
note: expected this to be `u8`
238-
--> $DIR/super-assoc-mismatch.rs:42:18
239-
|
240-
LL | type Assoc = T::Assoc;
241-
| ^^^^^^^^
242-
= help: see issue #48214
243-
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
244-
245143
error[E0277]: the trait bound `(): Sub` is not satisfied
246-
--> $DIR/super-assoc-mismatch.rs:66:34
144+
--> $DIR/super-assoc-mismatch.rs:62:34
247145
|
248146
LL | fn trivial_bound_wrapper() where Wrapper<()>: Sub {}
249147
| ^^^^^^^^^^^^^^^^ the trait `Sub` is not implemented for `()`, which is required by `Wrapper<()>: Sub`
@@ -260,26 +158,25 @@ LL | impl<T: Sub> Sub for Wrapper<T> {}
260158
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
261159

262160
error[E0277]: the trait bound `(): SubGeneric<u16>` is not satisfied
263-
--> $DIR/super-assoc-mismatch.rs:89:22
161+
--> $DIR/super-assoc-mismatch.rs:84:22
264162
|
265163
LL | type Assoc1<T> = ();
266164
| ^^ the trait `SubGeneric<u16>` is not implemented for `()`, which is required by `<u8 as MultiAssoc>::Assoc1<()>: SubGeneric<<u8 as MultiAssoc>::Assoc2>`
267165
|
268166
help: this trait has no implementations, consider adding one
269-
--> $DIR/super-assoc-mismatch.rs:77:1
167+
--> $DIR/super-assoc-mismatch.rs:72:1
270168
|
271169
LL | trait SubGeneric<T>: SuperGeneric<T, Assoc = T> {}
272170
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
273171
note: required by a bound in `MultiAssoc`
274-
--> $DIR/super-assoc-mismatch.rs:80:23
172+
--> $DIR/super-assoc-mismatch.rs:75:23
275173
|
276174
LL | trait MultiAssoc
277175
| ---------- required by a bound in this trait
278176
LL | where
279177
LL | Self::Assoc1<()>: SubGeneric<Self::Assoc2>
280178
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `MultiAssoc`
281179

282-
error: aborting due to 16 previous errors
180+
error: aborting due to 11 previous errors
283181

284-
Some errors have detailed explanations: E0271, E0277.
285-
For more information about an error, try `rustc --explain E0271`.
182+
For more information about this error, try `rustc --explain E0277`.

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

-3
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)