Skip to content

Commit 0e30c7d

Browse files
Rollup merge of rust-lang#125688 - compiler-errors:alias-reporting, r=lcnr
Walk into alias-eq nested goals even if normalization fails Somewhat broken due to the fact that we don't handle aliases well, nor do we handle ambiguities well. Still want to put up this incremental piece, since it improves type errors for projections whose trait refs are not satisfied. r? lcnr
2 parents 8337ba9 + 44040a0 commit 0e30c7d

23 files changed

+114
-40
lines changed

compiler/rustc_trait_selection/src/solve/alias_relate.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
4848
rhs
4949
};
5050

51+
// Add a `make_canonical_response` probe step so that we treat this as
52+
// a candidate, even if `try_evaluate_added_goals` bails due to an error.
53+
// It's `Certainty::AMBIGUOUS` because this candidate is not "finished",
54+
// since equating the normalized terms will lead to additional constraints.
55+
self.inspect.make_canonical_response(Certainty::AMBIGUOUS);
56+
5157
// Apply the constraints.
5258
self.try_evaluate_added_goals()?;
5359
let lhs = self.resolve_vars_if_possible(lhs);

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,10 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
460460
polarity: ty::PredicatePolarity::Positive,
461461
}))
462462
}
463-
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => {
464-
ChildMode::WellFormedObligation
465-
}
463+
ty::PredicateKind::Clause(
464+
ty::ClauseKind::WellFormed(_) | ty::ClauseKind::Projection(..),
465+
)
466+
| ty::PredicateKind::AliasRelate(..) => ChildMode::PassThrough,
466467
_ => {
467468
return ControlFlow::Break(self.obligation.clone());
468469
}
@@ -496,7 +497,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
496497
(_, GoalSource::InstantiateHigherRanked) => {
497498
obligation = self.obligation.clone();
498499
}
499-
(ChildMode::WellFormedObligation, _) => {
500+
(ChildMode::PassThrough, _) => {
500501
obligation = make_obligation(self.obligation.cause.clone());
501502
}
502503
}
@@ -527,7 +528,7 @@ enum ChildMode<'tcx> {
527528
// Skip trying to derive an `ObligationCause` from this obligation, and
528529
// report *all* sub-obligations as if they came directly from the parent
529530
// obligation.
530-
WellFormedObligation,
531+
PassThrough,
531532
}
532533

533534
fn derive_cause<'tcx>(

compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
1515
use rustc_macros::extension;
1616
use rustc_middle::traits::query::NoSolution;
1717
use rustc_middle::traits::solve::{inspect, QueryResult};
18-
use rustc_middle::traits::solve::{Certainty, Goal};
18+
use rustc_middle::traits::solve::{Certainty, Goal, MaybeCause};
1919
use rustc_middle::traits::ObligationCause;
2020
use rustc_middle::ty::{TyCtxt, TypeFoldable};
2121
use rustc_middle::{bug, ty};
@@ -291,7 +291,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
291291
steps.push(step)
292292
}
293293
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
294-
assert_eq!(shallow_certainty.replace(c), None);
294+
assert!(matches!(
295+
shallow_certainty.replace(c),
296+
None | Some(Certainty::Maybe(MaybeCause::Ambiguity))
297+
));
295298
}
296299
inspect::ProbeStep::NestedProbe(ref probe) => {
297300
match probe.kind {

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,6 +2705,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
27052705
),
27062706
);
27072707
}
2708+
2709+
ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })
2710+
if term.is_infer() =>
2711+
{
2712+
if let Some(e) = self.tainted_by_errors() {
2713+
return e;
2714+
}
2715+
struct_span_code_err!(
2716+
self.dcx(),
2717+
span,
2718+
E0284,
2719+
"type annotations needed: cannot normalize `{alias}`",
2720+
)
2721+
.with_span_label(span, format!("cannot normalize `{alias}`"))
2722+
}
2723+
27082724
_ => {
27092725
if let Some(e) = self.tainted_by_errors() {
27102726
return e;

tests/ui/coherence/indirect-impl-for-trait-obj-coherence.next.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0284]: type annotations needed: cannot satisfy `<dyn Object<U, Output = T> as Object<U>>::Output == T`
1+
error[E0284]: type annotations needed: cannot normalize `<dyn Object<U, Output = T> as Object<U>>::Output`
22
--> $DIR/indirect-impl-for-trait-obj-coherence.rs:25:41
33
|
44
LL | foo::<dyn Object<U, Output = T>, U>(x)
5-
| ^ cannot satisfy `<dyn Object<U, Output = T> as Object<U>>::Output == T`
5+
| ^ cannot normalize `<dyn Object<U, Output = T> as Object<U>>::Output`
66

77
error: aborting due to 1 previous error
88

tests/ui/coherence/indirect-impl-for-trait-obj-coherence.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn foo<T: ?Sized, U>(x: <T as Object<U>>::Output) -> U {
2323
#[allow(dead_code)]
2424
fn transmute<T, U>(x: T) -> U {
2525
foo::<dyn Object<U, Output = T>, U>(x)
26-
//[next]~^ ERROR type annotations needed: cannot satisfy `<dyn Object<U, Output = T> as Object<U>>::Output == T`
26+
//[next]~^ ERROR type annotations needed: cannot normalize `<dyn Object<U, Output = T> as Object<U>>::Output`
2727
}
2828

2929
fn main() {}

tests/ui/coherence/occurs-check/associated-type.next.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ LL | | for<'a> *const T: ToUnit<'a>,
1616
|
1717
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
1818

19-
error[E0284]: type annotations needed: cannot satisfy `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc == usize`
19+
error[E0284]: type annotations needed: cannot normalize `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc`
2020
--> $DIR/associated-type.rs:44:59
2121
|
2222
LL | foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);
23-
| ^^^^^^ cannot satisfy `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc == usize`
23+
| ^^^^^^ cannot normalize `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc`
2424

2525
error: aborting due to 2 previous errors
2626

tests/ui/coherence/occurs-check/associated-type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@ fn foo<T: Overlap<U>, U>(x: T::Assoc) -> T::Assoc {
4242

4343
fn main() {
4444
foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);
45-
//[next]~^ ERROR: cannot satisfy
45+
//[next]~^ ERROR: cannot normalize
4646
}

tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ LL | SelectInt.check("bar");
2525
= help: the trait `AsExpression<Text>` is implemented for `&str`
2626
= help: for that trait implementation, expected `Text`, found `Integer`
2727

28-
error[E0271]: type mismatch resolving `<&str as AsExpression<<SelectInt as Expression>::SqlType>>::Expression == _`
28+
error[E0271]: type mismatch resolving `<SelectInt as Expression>::SqlType == Text`
2929
--> $DIR/as_expression.rs:57:5
3030
|
3131
LL | SelectInt.check("bar");

tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0284]: type annotations needed: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: <T as Trait<'_>>::Assoc`
1+
error[E0284]: type annotations needed: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc normalizes-to <T as Trait<'_>>::Assoc`
22
--> $DIR/rigid-equate-projections-in-higher-ranked-fn-signature.rs:27:50
33
|
44
LL | let _: for<'a> fn(<_ as Trait<'a>>::Assoc) = foo::<T>();
5-
| ^^^^^^^^^^ cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: <T as Trait<'_>>::Assoc`
5+
| ^^^^^^^^^^ cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc normalizes-to <T as Trait<'_>>::Assoc`
66

77
error: aborting due to 1 previous error
88

0 commit comments

Comments
 (0)