diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs index 4d7e2fc2cef..59a8de99b8f 100644 --- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs +++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs @@ -48,6 +48,12 @@ pub(super) fn compute_alias_relate_goal( rhs }; + // Add a `make_canonical_response` probe step so that we treat this as + // a candidate, even if `try_evaluate_added_goals` bails due to an error. + // It's `Certainty::AMBIGUOUS` because this candidate is not "finished", + // since equating the normalized terms will lead to additional constraints. + self.inspect.make_canonical_response(Certainty::AMBIGUOUS); + // Apply the constraints. self.try_evaluate_added_goals()?; let lhs = self.resolve_vars_if_possible(lhs); diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index dc13941e5d7..3c3d5dfe79c 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -460,9 +460,10 @@ fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result polarity: ty::PredicatePolarity::Positive, })) } - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => { - ChildMode::WellFormedObligation - } + ty::PredicateKind::Clause( + ty::ClauseKind::WellFormed(_) | ty::ClauseKind::Projection(..), + ) + | ty::PredicateKind::AliasRelate(..) => ChildMode::PassThrough, _ => { return ControlFlow::Break(self.obligation.clone()); } @@ -496,7 +497,7 @@ fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result (_, GoalSource::InstantiateHigherRanked) => { obligation = self.obligation.clone(); } - (ChildMode::WellFormedObligation, _) => { + (ChildMode::PassThrough, _) => { obligation = make_obligation(self.obligation.cause.clone()); } } @@ -527,7 +528,7 @@ enum ChildMode<'tcx> { // Skip trying to derive an `ObligationCause` from this obligation, and // report *all* sub-obligations as if they came directly from the parent // obligation. - WellFormedObligation, + PassThrough, } fn derive_cause<'tcx>( diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 19c95dad48c..b9c98b6a2e9 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -15,7 +15,7 @@ use rustc_macros::extension; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{inspect, QueryResult}; -use rustc_middle::traits::solve::{Certainty, Goal}; +use rustc_middle::traits::solve::{Certainty, Goal, MaybeCause}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{TyCtxt, TypeFoldable}; use rustc_middle::{bug, ty}; @@ -291,7 +291,10 @@ fn candidates_recur( steps.push(step) } inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => { - assert_eq!(shallow_certainty.replace(c), None); + assert!(matches!( + shallow_certainty.replace(c), + None | Some(Certainty::Maybe(MaybeCause::Ambiguity)) + )); } inspect::ProbeStep::NestedProbe(ref probe) => { match probe.kind { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 6b6438a7887..a3ed51f43c9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -2705,6 +2705,22 @@ fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) -> Erro ), ); } + + ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) + if term.is_infer() => + { + if let Some(e) = self.tainted_by_errors() { + return e; + } + struct_span_code_err!( + self.dcx(), + span, + E0284, + "type annotations needed: cannot normalize `{alias}`", + ) + .with_span_label(span, format!("cannot normalize `{alias}`")) + } + _ => { if let Some(e) = self.tainted_by_errors() { return e; diff --git a/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.next.stderr b/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.next.stderr index 6e41561f1a7..b6636d4de86 100644 --- a/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.next.stderr +++ b/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.next.stderr @@ -1,8 +1,8 @@ -error[E0284]: type annotations needed: cannot satisfy ` as Object>::Output == T` +error[E0284]: type annotations needed: cannot normalize ` as Object>::Output` --> $DIR/indirect-impl-for-trait-obj-coherence.rs:25:41 | LL | foo::, U>(x) - | ^ cannot satisfy ` as Object>::Output == T` + | ^ cannot normalize ` as Object>::Output` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.rs b/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.rs index 0b66a6e7830..abfd51c2008 100644 --- a/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.rs +++ b/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.rs @@ -23,7 +23,7 @@ fn foo(x: >::Output) -> U { #[allow(dead_code)] fn transmute(x: T) -> U { foo::, U>(x) - //[next]~^ ERROR type annotations needed: cannot satisfy ` as Object>::Output == T` + //[next]~^ ERROR type annotations needed: cannot normalize ` as Object>::Output` } fn main() {} diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index f32bb1301da..bd65cee58d9 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr @@ -16,11 +16,11 @@ LL | | for<'a> *const T: ToUnit<'a>, | = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details -error[E0284]: type annotations needed: cannot satisfy ` fn(&'a (), ()) as Overlap fn(&'a (), ())>>::Assoc == usize` +error[E0284]: type annotations needed: cannot normalize ` fn(&'a (), ()) as Overlap fn(&'a (), ())>>::Assoc` --> $DIR/associated-type.rs:44:59 | LL | foo:: fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize); - | ^^^^^^ cannot satisfy ` fn(&'a (), ()) as Overlap fn(&'a (), ())>>::Assoc == usize` + | ^^^^^^ cannot normalize ` fn(&'a (), ()) as Overlap fn(&'a (), ())>>::Assoc` error: aborting due to 2 previous errors diff --git a/tests/ui/coherence/occurs-check/associated-type.rs b/tests/ui/coherence/occurs-check/associated-type.rs index ac1236c554a..df03d5f60a0 100644 --- a/tests/ui/coherence/occurs-check/associated-type.rs +++ b/tests/ui/coherence/occurs-check/associated-type.rs @@ -42,5 +42,5 @@ fn foo, U>(x: T::Assoc) -> T::Assoc { fn main() { foo:: fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize); - //[next]~^ ERROR: cannot satisfy + //[next]~^ ERROR: cannot normalize } diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr index 568cb8931a1..d189d2dbded 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr @@ -25,7 +25,7 @@ LL | SelectInt.check("bar"); = help: the trait `AsExpression` is implemented for `&str` = help: for that trait implementation, expected `Text`, found `Integer` -error[E0271]: type mismatch resolving `<&str as AsExpression<::SqlType>>::Expression == _` +error[E0271]: type mismatch resolving `::SqlType == Text` --> $DIR/as_expression.rs:57:5 | LL | SelectInt.check("bar"); diff --git a/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr index 14a3d5e178d..31d74d1c022 100644 --- a/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr +++ b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr @@ -1,8 +1,8 @@ -error[E0284]: type annotations needed: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: >::Assoc` +error[E0284]: type annotations needed: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc normalizes-to >::Assoc` --> $DIR/rigid-equate-projections-in-higher-ranked-fn-signature.rs:27:50 | LL | let _: for<'a> fn(<_ as Trait<'a>>::Assoc) = foo::(); - | ^^^^^^^^^^ cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: >::Assoc` + | ^^^^^^^^^^ cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc normalizes-to >::Assoc` error: aborting due to 1 previous error diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs index 2607f047024..35757f2339d 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs @@ -18,3 +18,4 @@ fn weird1() -> impl !Sized + Sized {} //~^ ERROR type mismatch resolving `impl !Sized + Sized == ()` fn weird2() -> impl !Sized {} //~^ ERROR type mismatch resolving `impl !Sized == ()` +//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr index ceaf42431fe..3dd2b27b55b 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr @@ -16,6 +16,15 @@ error[E0271]: type mismatch resolving `impl !Sized == ()` LL | fn weird2() -> impl !Sized {} | ^^^^^^^^^^^ types differ +error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 + | +LL | fn weird2() -> impl !Sized {} + | ^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl !Sized` + = note: the return type of a function must have a statically known size + error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:12:13 | @@ -30,7 +39,7 @@ note: required by a bound in `consume` LL | fn consume(_: impl Trait) {} | ^^^^^ required by this bound in `consume` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0271, E0277. For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/canonical/const-region-infer-to-static-in-binder.stderr b/tests/ui/traits/next-solver/canonical/const-region-infer-to-static-in-binder.stderr index 9dde1963bd4..e0cbee88aa1 100644 --- a/tests/ui/traits/next-solver/canonical/const-region-infer-to-static-in-binder.stderr +++ b/tests/ui/traits/next-solver/canonical/const-region-infer-to-static-in-binder.stderr @@ -1,8 +1,8 @@ -error[E0284]: type annotations needed: cannot satisfy `{ || {} } == _` +error[E0284]: type annotations needed: cannot normalize `X::{constant#0}` --> $DIR/const-region-infer-to-static-in-binder.rs:4:10 | LL | struct X; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `{ || {} } == _` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `X::{constant#0}` error: using function pointers as const generic parameters is forbidden --> $DIR/const-region-infer-to-static-in-binder.rs:4:20 diff --git a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.rs b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.rs new file mode 100644 index 00000000000..a3ab7bf03e5 --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Znext-solver + +trait Trait { + type Assoc; +} + +fn test_poly() { + let x: ::Assoc = (); + //~^ ERROR the trait bound `T: Trait` is not satisfied +} + +fn test() { + let x: ::Assoc = (); + //~^ ERROR the trait bound `i32: Trait` is not satisfied +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr new file mode 100644 index 00000000000..cd8d8b3ffcd --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr @@ -0,0 +1,26 @@ +error[E0277]: the trait bound `T: Trait` is not satisfied + --> $DIR/projection-trait-ref.rs:8:12 + | +LL | let x: ::Assoc = (); + | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | fn test_poly() { + | +++++++ + +error[E0277]: the trait bound `i32: Trait` is not satisfied + --> $DIR/projection-trait-ref.rs:13:12 + | +LL | let x: ::Assoc = (); + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `i32` + | +help: this trait has no implementations, consider adding one + --> $DIR/projection-trait-ref.rs:3:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr index 3ef0afa38bf..0c72fc25dca 100644 --- a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr +++ b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr @@ -2,13 +2,8 @@ error[E0271]: type mismatch resolving `::Assoc == i32` --> $DIR/param-candidate-shadows-project.rs:27:19 | LL | require_bar::(); - | ^ type mismatch resolving `::Assoc == i32` + | ^ types differ | -note: types differ - --> $DIR/param-candidate-shadows-project.rs:10:18 - | -LL | type Assoc = i32; - | ^^^ note: required for `T` to implement `Bar` --> $DIR/param-candidate-shadows-project.rs:13:9 | diff --git a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs index 12ea1bf142a..5239474ff44 100644 --- a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs +++ b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs @@ -24,7 +24,7 @@ fn needs_bar() {} fn foo + Foo>() { needs_bar::(); - //~^ ERROR type annotations needed: cannot satisfy `::Assoc == i32` + //~^ ERROR type annotations needed: cannot normalize } fn main() {} diff --git a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr index 21f3fbfeb87..270ad851717 100644 --- a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr +++ b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr @@ -1,8 +1,8 @@ -error[E0284]: type annotations needed: cannot satisfy `::Assoc == i32` +error[E0284]: type annotations needed: cannot normalize `::Assoc` --> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:17 | LL | needs_bar::(); - | ^ cannot satisfy `::Assoc == i32` + | ^ cannot normalize `::Assoc` | note: required for `T` to implement `Bar` --> $DIR/two-projection-param-candidates-are-ambiguous.rs:21:9 diff --git a/tests/ui/traits/next-solver/specialization-transmute.stderr b/tests/ui/traits/next-solver/specialization-transmute.stderr index 524522bef09..b96bfab927d 100644 --- a/tests/ui/traits/next-solver/specialization-transmute.stderr +++ b/tests/ui/traits/next-solver/specialization-transmute.stderr @@ -10,23 +10,23 @@ LL | #![feature(specialization)] error: cannot normalize `::Id: '_` -error[E0284]: type annotations needed: cannot satisfy `::Id == _` +error[E0284]: type annotations needed: cannot normalize `::Id` --> $DIR/specialization-transmute.rs:15:23 | LL | fn intu(&self) -> &Self::Id { - | ^^^^^^^^^ cannot satisfy `::Id == _` + | ^^^^^^^^^ cannot normalize `::Id` -error[E0284]: type annotations needed: cannot satisfy `T <: ::Id` +error[E0284]: type annotations needed: cannot satisfy `::Id normalizes-to T` --> $DIR/specialization-transmute.rs:17:9 | LL | self - | ^^^^ cannot satisfy `T <: ::Id` + | ^^^^ cannot satisfy `::Id normalizes-to T` -error[E0284]: type annotations needed: cannot satisfy `::Id == Option>` +error[E0284]: type annotations needed: cannot satisfy `::Id normalizes-to Option>` --> $DIR/specialization-transmute.rs:28:13 | LL | let s = transmute::>>(0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `::Id == Option>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `::Id normalizes-to Option>` | note: required by a bound in `transmute` --> $DIR/specialization-transmute.rs:21:25 diff --git a/tests/ui/traits/next-solver/specialization-unconstrained.rs b/tests/ui/traits/next-solver/specialization-unconstrained.rs index e44246a1262..2bbe7840110 100644 --- a/tests/ui/traits/next-solver/specialization-unconstrained.rs +++ b/tests/ui/traits/next-solver/specialization-unconstrained.rs @@ -18,5 +18,5 @@ fn test, U>() {} fn main() { test::(); - //~^ ERROR cannot satisfy `::Id == ()` + //~^ ERROR cannot satisfy `::Id normalizes-to ()` } diff --git a/tests/ui/traits/next-solver/specialization-unconstrained.stderr b/tests/ui/traits/next-solver/specialization-unconstrained.stderr index a6f6a4f260d..e1d785b554b 100644 --- a/tests/ui/traits/next-solver/specialization-unconstrained.stderr +++ b/tests/ui/traits/next-solver/specialization-unconstrained.stderr @@ -8,11 +8,11 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete = note: `#[warn(incomplete_features)]` on by default -error[E0284]: type annotations needed: cannot satisfy `::Id == ()` +error[E0284]: type annotations needed: cannot satisfy `::Id normalizes-to ()` --> $DIR/specialization-unconstrained.rs:20:5 | LL | test::(); - | ^^^^^^^^^^^^^^^^^ cannot satisfy `::Id == ()` + | ^^^^^^^^^^^^^^^^^ cannot satisfy `::Id normalizes-to ()` | note: required by a bound in `test` --> $DIR/specialization-unconstrained.rs:17:20 diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr index 4c8a25edfed..5a728a00138 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr @@ -1,4 +1,4 @@ -error[E0284]: type annotations needed: cannot satisfy `>::Out == ()` +error[E0284]: type annotations needed: cannot satisfy `Bar == _` --> $DIR/issue-84660-unsoundness.rs:22:37 | LL | fn convert(_i: In) -> Self::Out { @@ -7,7 +7,7 @@ LL | | LL | | LL | | unreachable!(); LL | | } - | |_____^ cannot satisfy `>::Out == ()` + | |_____^ cannot satisfy `Bar == _` error[E0119]: conflicting implementations of trait `Trait` --> $DIR/issue-84660-unsoundness.rs:29:1 diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs index 73c8deb3a4d..f3234bafd11 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -20,7 +20,7 @@ trait Trait { impl Trait for Out { type Out = Out; fn convert(_i: In) -> Self::Out { - //[next]~^ ERROR: cannot satisfy `>::Out == ()` + //[next]~^ ERROR: cannot satisfy `Bar == _` //[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`, but has it in its signature unreachable!(); }