Skip to content

Commit 374b121

Browse files
committed
update diagnostics
1 parent d2c0c50 commit 374b121

17 files changed

+150
-55
lines changed

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
6161
let tcx = self.tcx;
6262
let mut span = obligation.cause.span;
6363
let mut long_ty_file = None;
64-
6564
let mut err = match *error {
6665
SelectionError::Unimplemented => {
6766
// If this obligation was generated as a result of well-formedness checking, see if we
@@ -585,6 +584,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
585584
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => {
586585
let ty = self.resolve_vars_if_possible(ty);
587586
if self.next_trait_solver() {
587+
if let Err(guar) = ty.error_reported() {
588+
return guar;
589+
}
590+
588591
// FIXME: we'll need a better message which takes into account
589592
// which bounds actually failed to hold.
590593
self.dcx().struct_span_err(
@@ -1201,6 +1204,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
12011204
}
12021205

12031206
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
1207+
#[instrument(level = "trace", skip(self), ret)]
12041208
fn can_match_trait(
12051209
&self,
12061210
goal: ty::TraitPredicate<'tcx>,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
172172
{
173173
1
174174
}
175-
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3,
176175
ty::PredicateKind::Coerce(_) => 2,
176+
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3,
177177
_ => 0,
178178
});
179179

compiler/rustc_trait_selection/src/infer.rs

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt, Selection
1919

2020
#[extension(pub trait InferCtxtExt<'tcx>)]
2121
impl<'tcx> InferCtxt<'tcx> {
22+
#[instrument(level = "trace", skip(self), ret)]
2223
fn can_eq<T: ToTrace<'tcx>>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool {
2324
self.probe(|_| {
2425
let ocx = ObligationCtxt::new(self);

compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs

+32-10
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ pub(super) fn fulfillment_error_for_overflow<'tcx>(
139139
}
140140
}
141141

142+
#[instrument(level = "debug", skip(infcx), ret)]
142143
fn find_best_leaf_obligation<'tcx>(
143144
infcx: &InferCtxt<'tcx>,
144145
obligation: &PredicateObligation<'tcx>,
@@ -211,11 +212,7 @@ impl<'tcx> BestObligation<'tcx> {
211212
| GoalSource::AliasBoundConstCondition
212213
| GoalSource::InstantiateHigherRanked
213214
| GoalSource::AliasWellFormed
214-
) && match (self.consider_ambiguities, nested_goal.result()) {
215-
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity)))
216-
| (false, Err(_)) => true,
217-
_ => false,
218-
}
215+
) && nested_goal.result().is_err()
219216
},
220217
)
221218
})
@@ -277,11 +274,37 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
277274

278275
#[instrument(level = "trace", skip(self, goal), fields(goal = ?goal.goal()))]
279276
fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
277+
let tcx = goal.infcx().tcx;
278+
let pred_kind = goal.goal().predicate.kind();
279+
280280
let candidates = self.non_trivial_candidates(goal);
281-
trace!(candidates = ?candidates.iter().map(|c| c.kind()).collect::<Vec<_>>());
281+
let candidate = match candidates.as_slice() {
282+
[] => {
283+
// Similar to `AliasRelate` goals, `NormalizesTo` may fail because the
284+
// used alias is not well-formed. We only enter an actual `RigidAlias`
285+
// candidate if its trait bound was proven via the environment. We therefore
286+
// manually check whether the alias is even well-formed here.
287+
if let Some(ty::PredicateKind::NormalizesTo(pred)) = pred_kind.no_bound_vars() {
288+
if let Some(obligation) = goal
289+
.infcx()
290+
.visit_proof_tree_at_depth(
291+
goal.goal().with(
292+
goal.infcx().tcx,
293+
ty::ClauseKind::WellFormed(pred.alias.to_term(tcx).into()),
294+
),
295+
goal.depth() + 1,
296+
self,
297+
)
298+
.break_value()
299+
{
300+
return ControlFlow::Break(obligation);
301+
}
302+
}
282303

283-
let [candidate] = candidates.as_slice() else {
284-
return ControlFlow::Break(self.obligation.clone());
304+
return ControlFlow::Break(self.obligation.clone());
305+
}
306+
[candidate] => candidate,
307+
_ => return ControlFlow::Break(self.obligation.clone()),
285308
};
286309

287310
// Don't walk into impls that have `do_not_recommend`.
@@ -291,13 +314,12 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
291314
} = candidate.kind()
292315
&& goal.infcx().tcx.do_not_recommend_impl(impl_def_id)
293316
{
317+
trace!("#[do_not_recommend] -> exit");
294318
return ControlFlow::Break(self.obligation.clone());
295319
}
296320

297-
let tcx = goal.infcx().tcx;
298321
// FIXME: Also, what about considering >1 layer up the stack? May be necessary
299322
// for normalizes-to.
300-
let pred_kind = goal.goal().predicate.kind();
301323
let child_mode = match pred_kind.skip_binder() {
302324
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
303325
ChildMode::Trait(pred_kind.rebind(pred))

tests/ui/associated-types/defaults-unsound-62211-1.next.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@ error[E0277]: the trait bound `Self: Deref` is not satisfied
3737
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
3838
| ^^^^ the trait `Deref` is not implemented for `Self`
3939
|
40-
note: required by a bound in `UncheckedCopy::Output`
41-
--> $DIR/defaults-unsound-62211-1.rs:24:31
42-
|
43-
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
44-
| ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
4540
help: consider further restricting `Self`
4641
|
4742
LL | trait UncheckedCopy: Sized + Deref {

tests/ui/associated-types/defaults-unsound-62211-2.next.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@ error[E0277]: the trait bound `Self: Deref` is not satisfied
3737
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
3838
| ^^^^ the trait `Deref` is not implemented for `Self`
3939
|
40-
note: required by a bound in `UncheckedCopy::Output`
41-
--> $DIR/defaults-unsound-62211-2.rs:24:31
42-
|
43-
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
44-
| ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
4540
help: consider further restricting `Self`
4641
|
4742
LL | trait UncheckedCopy: Sized + Deref {

tests/ui/associated-types/issue-54108.next.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ LL | type Size = <Self as SubEncoder>::ActualSize;
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `<T as SubEncoder>::ActualSize + <T as SubEncoder>::ActualSize`
66
|
77
= help: the trait `Add` is not implemented for `<T as SubEncoder>::ActualSize`
8-
note: required by a bound in `Encoder::Size`
9-
--> $DIR/issue-54108.rs:8:20
10-
|
11-
LL | type Size: Add<Output = Self::Size>;
12-
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
138
help: consider further restricting the associated type
149
|
1510
LL - T: SubEncoder,

tests/ui/auto-traits/assoc-ty.next.stderr

+13-12
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,21 @@ LL | | }
2121
= help: add `#![feature(auto_traits)]` to the crate attributes to enable
2222
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2323

24-
error[E0308]: mismatched types
25-
--> $DIR/assoc-ty.rs:15:36
24+
error[E0271]: type mismatch resolving `<() as Trait>::Output normalizes-to _`
25+
--> $DIR/assoc-ty.rs:15:12
2626
|
2727
LL | let _: <() as Trait>::Output = ();
28-
| --------------------- ^^ types differ
29-
| |
30-
| expected due to this
28+
| ^^^^^^^^^^^^^^^^^^^^^ types differ
29+
30+
error[E0271]: type mismatch resolving `<() as Trait>::Output normalizes-to _`
31+
--> $DIR/assoc-ty.rs:15:12
32+
|
33+
LL | let _: <() as Trait>::Output = ();
34+
| ^^^^^^^^^^^^^^^^^^^^^ types differ
3135
|
32-
= note: expected associated type `<() as Trait>::Output`
33-
found unit type `()`
34-
= help: consider constraining the associated type `<() as Trait>::Output` to `()` or calling a method that returns `<() as Trait>::Output`
35-
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
36+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
3637

37-
error: aborting due to 3 previous errors
38+
error: aborting due to 4 previous errors
3839

39-
Some errors have detailed explanations: E0308, E0380, E0658.
40-
For more information about an error, try `rustc --explain E0308`.
40+
Some errors have detailed explanations: E0271, E0380, E0658.
41+
For more information about an error, try `rustc --explain E0271`.

tests/ui/auto-traits/assoc-ty.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ auto trait Trait {
1313

1414
fn main() {
1515
let _: <() as Trait>::Output = ();
16-
//~^ ERROR mismatched types
16+
//[current]~^ ERROR mismatched types
17+
//[next]~^^ ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
18+
//[next]~| ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
1719
}

tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,19 @@ error[E0271]: type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> == ()`
2323
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
2424
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
2525

26-
error: aborting due to 3 previous errors
26+
error[E0271]: type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
27+
--> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:73
28+
|
29+
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
30+
| ^^ types differ
31+
32+
error[E0271]: type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
33+
--> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:5
34+
|
35+
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
36+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
37+
38+
error: aborting due to 5 previous errors
2739

2840
Some errors have detailed explanations: E0049, E0271, E0407.
2941
For more information about an error, try `rustc --explain E0049`.

tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ impl X for Y {
2626
//~^ ERROR type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
2727
type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>>;
2828
fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
29-
//[current]~^ ERROR `()` is not a future
30-
//[next]~^^ ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> == ()`
31-
//~^^^ method `line_stream` is not a member of trait `X`
29+
//~^ method `line_stream` is not a member of trait `X`
30+
//[current]~^^ ERROR `()` is not a future
31+
//[next]~^^^ ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> == ()`
32+
//[next]~| ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
33+
//[next]~| ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
3234
}
3335

3436
pub fn main() {}

tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed

+2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ fn main() {
66
let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
77
//[current]~^ ERROR type mismatch in closure arguments
88
//[next]~^^ ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found
9+
//[next]~| ERROR expected a `FnOnce(&{integer})` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
910
let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
1011
//[current]~^ ERROR type mismatch in closure arguments
1112
//[next]~^^ ERROR expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}`
1213
//[next]~| ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found
14+
//[next]~| ERROR expected a `FnOnce(&{integer})` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:10:29: 10:40}`
1315
}

tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ LL | let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
1616
| +
1717

1818
error[E0631]: type mismatch in closure arguments
19-
--> $DIR/closure-arg-type-mismatch-issue-45727.rs:9:24
19+
--> $DIR/closure-arg-type-mismatch-issue-45727.rs:10:24
2020
|
2121
LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
2222
| ^^^^ ----------- found signature defined here

tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr

+26-6
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,47 @@ LL | let _ = (-10..=10).find(|x: i32| x.signum() == 0);
1212
note: required by a bound in `find`
1313
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
1414

15+
error[E0277]: expected a `FnOnce(&{integer})` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
16+
--> $DIR/closure-arg-type-mismatch-issue-45727.rs:6:24
17+
|
18+
LL | let _ = (-10..=10).find(|x: i32| x.signum() == 0);
19+
| ^^^^ expected an `FnOnce(&{integer})` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
20+
|
21+
= help: the trait `for<'a> FnOnce(&'a {integer})` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
22+
= note: expected a closure with arguments `(i32,)`
23+
found a closure with arguments `(&{integer},)`
24+
1525
error[E0271]: expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}`
16-
--> $DIR/closure-arg-type-mismatch-issue-45727.rs:9:24
26+
--> $DIR/closure-arg-type-mismatch-issue-45727.rs:10:24
1727
|
1828
LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
1929
| ^^^^ expected `&&i32`, found integer
2030

21-
error[E0277]: expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}`
22-
--> $DIR/closure-arg-type-mismatch-issue-45727.rs:9:29
31+
error[E0277]: expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:10:29: 10:40}`
32+
--> $DIR/closure-arg-type-mismatch-issue-45727.rs:10:29
2333
|
2434
LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
25-
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}`
35+
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:10:29: 10:40}`
2636
| |
2737
| required by a bound introduced by this call
2838
|
29-
= help: the trait `for<'a> FnMut(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}`
39+
= help: the trait `for<'a> FnMut(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:10:29: 10:40}`
3040
= note: expected a closure with arguments `(&&&i32,)`
3141
found a closure with arguments `(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item,)`
3242
note: required by a bound in `find`
3343
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
3444

35-
error: aborting due to 3 previous errors
45+
error[E0277]: expected a `FnOnce(&{integer})` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:10:29: 10:40}`
46+
--> $DIR/closure-arg-type-mismatch-issue-45727.rs:10:24
47+
|
48+
LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
49+
| ^^^^ expected an `FnOnce(&{integer})` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:10:29: 10:40}`
50+
|
51+
= help: the trait `for<'a> FnOnce(&'a {integer})` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:10:29: 10:40}`
52+
= note: expected a closure with arguments `(&&&i32,)`
53+
found a closure with arguments `(&{integer},)`
54+
55+
error: aborting due to 5 previous errors
3656

3757
Some errors have detailed explanations: E0271, E0277.
3858
For more information about an error, try `rustc --explain E0271`.

tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs

+2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ fn main() {
66
let _ = (-10..=10).find(|x: i32| x.signum() == 0);
77
//[current]~^ ERROR type mismatch in closure arguments
88
//[next]~^^ ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found
9+
//[next]~| ERROR expected a `FnOnce(&{integer})` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
910
let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
1011
//[current]~^ ERROR type mismatch in closure arguments
1112
//[next]~^^ ERROR expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}`
1213
//[next]~| ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found
14+
//[next]~| ERROR expected a `FnOnce(&{integer})` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:10:29: 10:40}`
1315
}

tests/ui/traits/next-solver/fn-trait.rs

+4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ fn main() {
1919
require_fn(f as fn() -> i32);
2020
require_fn(f as unsafe fn() -> i32);
2121
//~^ ERROR: expected a `Fn()` closure, found `unsafe fn() -> i32`
22+
//~| ERROR: expected a `FnOnce()` closure, found `unsafe fn() -> i32`
2223
require_fn(g);
2324
//~^ ERROR: expected a `Fn()` closure, found `extern "C" fn() -> i32 {g}`
25+
//~| ERROR: expected a `FnOnce()` closure, found `extern "C" fn() -> i32 {g}`
2426
require_fn(g as extern "C" fn() -> i32);
2527
//~^ ERROR: expected a `Fn()` closure, found `extern "C" fn() -> i32`
28+
//~| ERROR: expected a `FnOnce()` closure, found `extern "C" fn() -> i32`
2629
require_fn(h);
2730
//~^ ERROR: expected a `Fn()` closure, found `unsafe fn() -> i32 {h}`
31+
//~| ERROR: expected a `FnOnce()` closure, found `unsafe fn() -> i32 {h}`
2832
}

0 commit comments

Comments
 (0)