Skip to content

Commit

Permalink
Rollup merge of rust-lang#125688 - compiler-errors:alias-reporting, r…
Browse files Browse the repository at this point in the history
…=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
  • Loading branch information
workingjubilee committed Jun 13, 2024
2 parents b1a6d44 + 44040a0 commit dd6df05
Show file tree
Hide file tree
Showing 23 changed files with 114 additions and 40 deletions.
6 changes: 6 additions & 0 deletions compiler/rustc_trait_selection/src/solve/alias_relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
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);
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_trait_selection/src/solve/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,10 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
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());
}
Expand Down Expand Up @@ -496,7 +497,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
(_, GoalSource::InstantiateHigherRanked) => {
obligation = self.obligation.clone();
}
(ChildMode::WellFormedObligation, _) => {
(ChildMode::PassThrough, _) => {
obligation = make_obligation(self.obligation.cause.clone());
}
}
Expand Down Expand Up @@ -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>(
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
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};
Expand Down Expand Up @@ -291,7 +291,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2705,6 +2705,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
),
);
}

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;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0284]: type annotations needed: cannot satisfy `<dyn Object<U, Output = T> as Object<U>>::Output == T`
error[E0284]: type annotations needed: cannot normalize `<dyn Object<U, Output = T> as Object<U>>::Output`
--> $DIR/indirect-impl-for-trait-obj-coherence.rs:25:41
|
LL | foo::<dyn Object<U, Output = T>, U>(x)
| ^ cannot satisfy `<dyn Object<U, Output = T> as Object<U>>::Output == T`
| ^ cannot normalize `<dyn Object<U, Output = T> as Object<U>>::Output`

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn foo<T: ?Sized, U>(x: <T as Object<U>>::Output) -> U {
#[allow(dead_code)]
fn transmute<T, U>(x: T) -> U {
foo::<dyn Object<U, Output = T>, U>(x)
//[next]~^ ERROR type annotations needed: cannot satisfy `<dyn Object<U, Output = T> as Object<U>>::Output == T`
//[next]~^ ERROR type annotations needed: cannot normalize `<dyn Object<U, Output = T> as Object<U>>::Output`
}

fn main() {}
4 changes: 2 additions & 2 deletions tests/ui/coherence/occurs-check/associated-type.next.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc == usize`
error[E0284]: type annotations needed: cannot normalize `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc`
--> $DIR/associated-type.rs:44:59
|
LL | foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);
| ^^^^^^ cannot satisfy `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc == usize`
| ^^^^^^ cannot normalize `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc`

error: aborting due to 2 previous errors

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/coherence/occurs-check/associated-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ fn foo<T: Overlap<U>, U>(x: T::Assoc) -> T::Assoc {

fn main() {
foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);
//[next]~^ ERROR: cannot satisfy
//[next]~^ ERROR: cannot normalize
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ LL | SelectInt.check("bar");
= help: the trait `AsExpression<Text>` is implemented for `&str`
= help: for that trait implementation, expected `Text`, found `Integer`

error[E0271]: type mismatch resolving `<&str as AsExpression<<SelectInt as Expression>::SqlType>>::Expression == _`
error[E0271]: type mismatch resolving `<SelectInt as Expression>::SqlType == Text`
--> $DIR/as_expression.rs:57:5
|
LL | SelectInt.check("bar");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0284]: type annotations needed: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: <T as Trait<'_>>::Assoc`
error[E0284]: type annotations needed: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc normalizes-to <T as Trait<'_>>::Assoc`
--> $DIR/rigid-equate-projections-in-higher-ranked-fn-signature.rs:27:50
|
LL | let _: for<'a> fn(<_ as Trait<'a>>::Assoc) = foo::<T>();
| ^^^^^^^^^^ cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: <T as Trait<'_>>::Assoc`
| ^^^^^^^^^^ cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc normalizes-to <T as Trait<'_>>::Assoc`

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand All @@ -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`.
Original file line number Diff line number Diff line change
@@ -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<const FN: fn() = { || {} }>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/traits/next-solver/diagnostics/projection-trait-ref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ compile-flags: -Znext-solver

trait Trait {
type Assoc;
}

fn test_poly<T>() {
let x: <T as Trait>::Assoc = ();
//~^ ERROR the trait bound `T: Trait` is not satisfied
}

fn test() {
let x: <i32 as Trait>::Assoc = ();
//~^ ERROR the trait bound `i32: Trait` is not satisfied
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error[E0277]: the trait bound `T: Trait` is not satisfied
--> $DIR/projection-trait-ref.rs:8:12
|
LL | let x: <T as Trait>::Assoc = ();
| ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
LL | fn test_poly<T: Trait>() {
| +++++++

error[E0277]: the trait bound `i32: Trait` is not satisfied
--> $DIR/projection-trait-ref.rs:13:12
|
LL | let x: <i32 as Trait>::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`.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@ error[E0271]: type mismatch resolving `<T as Foo>::Assoc == i32`
--> $DIR/param-candidate-shadows-project.rs:27:19
|
LL | require_bar::<T>();
| ^ type mismatch resolving `<T as Foo>::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
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn needs_bar<T: Bar>() {}

fn foo<T: Foo<Assoc = i32> + Foo<Assoc = u32>>() {
needs_bar::<T>();
//~^ ERROR type annotations needed: cannot satisfy `<T as Foo>::Assoc == i32`
//~^ ERROR type annotations needed: cannot normalize
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0284]: type annotations needed: cannot satisfy `<T as Foo>::Assoc == i32`
error[E0284]: type annotations needed: cannot normalize `<T as Foo>::Assoc`
--> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:17
|
LL | needs_bar::<T>();
| ^ cannot satisfy `<T as Foo>::Assoc == i32`
| ^ cannot normalize `<T as Foo>::Assoc`
|
note: required for `T` to implement `Bar`
--> $DIR/two-projection-param-candidates-are-ambiguous.rs:21:9
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/traits/next-solver/specialization-transmute.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ LL | #![feature(specialization)]

error: cannot normalize `<T as Default>::Id: '_`

error[E0284]: type annotations needed: cannot satisfy `<T as Default>::Id == _`
error[E0284]: type annotations needed: cannot normalize `<T as Default>::Id`
--> $DIR/specialization-transmute.rs:15:23
|
LL | fn intu(&self) -> &Self::Id {
| ^^^^^^^^^ cannot satisfy `<T as Default>::Id == _`
| ^^^^^^^^^ cannot normalize `<T as Default>::Id`

error[E0284]: type annotations needed: cannot satisfy `T <: <T as Default>::Id`
error[E0284]: type annotations needed: cannot satisfy `<T as Default>::Id normalizes-to T`
--> $DIR/specialization-transmute.rs:17:9
|
LL | self
| ^^^^ cannot satisfy `T <: <T as Default>::Id`
| ^^^^ cannot satisfy `<T as Default>::Id normalizes-to T`

error[E0284]: type annotations needed: cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>`
error[E0284]: type annotations needed: cannot satisfy `<u8 as Default>::Id normalizes-to Option<NonZero<u8>>`
--> $DIR/specialization-transmute.rs:28:13
|
LL | let s = transmute::<u8, Option<NonZero<u8>>>(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<u8 as Default>::Id normalizes-to Option<NonZero<u8>>`
|
note: required by a bound in `transmute`
--> $DIR/specialization-transmute.rs:21:25
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ fn test<T: Default<Id = U>, U>() {}

fn main() {
test::<u32, ()>();
//~^ ERROR cannot satisfy `<u32 as Default>::Id == ()`
//~^ ERROR cannot satisfy `<u32 as Default>::Id normalizes-to ()`
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<u32 as Default>::Id == ()`
error[E0284]: type annotations needed: cannot satisfy `<u32 as Default>::Id normalizes-to ()`
--> $DIR/specialization-unconstrained.rs:20:5
|
LL | test::<u32, ()>();
| ^^^^^^^^^^^^^^^^^ cannot satisfy `<u32 as Default>::Id == ()`
| ^^^^^^^^^^^^^^^^^ cannot satisfy `<u32 as Default>::Id normalizes-to ()`
|
note: required by a bound in `test`
--> $DIR/specialization-unconstrained.rs:17:20
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0284]: type annotations needed: cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
error[E0284]: type annotations needed: cannot satisfy `Bar == _`
--> $DIR/issue-84660-unsoundness.rs:22:37
|
LL | fn convert(_i: In) -> Self::Out {
Expand All @@ -7,7 +7,7 @@ LL | |
LL | |
LL | | unreachable!();
LL | | }
| |_____^ cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
| |_____^ cannot satisfy `Bar == _`

error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
--> $DIR/issue-84660-unsoundness.rs:29:1
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ trait Trait<T, In> {
impl<In, Out> Trait<Bar, In> for Out {
type Out = Out;
fn convert(_i: In) -> Self::Out {
//[next]~^ ERROR: cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
//[next]~^ ERROR: cannot satisfy `Bar == _`
//[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`, but has it in its signature
unreachable!();
}
Expand Down

0 comments on commit dd6df05

Please sign in to comment.