Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let param_env = self.infcx.param_env;
// Upcast to a `Clause`, then to a `Predicate`.
let predicate = clause.upcast(self.tcx()).upcast(self.tcx());
let _: Result<_, ErrorGuaranteed> = self.fully_perform_op(
let _: Result<(), ErrorGuaranteed> = self.fully_perform_op(
locations,
category,
param_env.and(type_op::prove_predicate::ProvePredicate { predicate }),
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_infer::traits::PredicateObligations;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::{ParamEnvAnd, TyCtxt, TypeFoldable};
use rustc_span::Span;
use tracing::debug;

use crate::infer::canonical::{
CanonicalQueryInput, CanonicalQueryResponse, Certainty, OriginalQueryValues,
Expand Down Expand Up @@ -93,14 +94,13 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
Self::QueryResponse,
Option<CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>>,
PredicateObligations<'tcx>,
Certainty,
),
NoSolution,
> {
if !infcx.disable_trait_solver_fast_paths()
&& let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key)
{
return Ok((result, None, PredicateObligations::new(), Certainty::Proven));
return Ok((result, None, PredicateObligations::new()));
}

let mut canonical_var_values = OriginalQueryValues::default();
Expand All @@ -117,7 +117,15 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
output_query_region_constraints,
)?;

Ok((value, Some(canonical_self), obligations, canonical_result.value.certainty))
match canonical_result.value.certainty {
Certainty::Proven => {}
Certainty::Ambiguous => {
debug!("type_op resulted in unexpected ambiguity: {query_key:?}");
return Err(NoSolution);
}
}

Ok((value, Some(canonical_self), obligations))
}
}

Expand All @@ -143,7 +151,7 @@ where
// collecting region constraints via `region_constraints`.
let (mut output, _) =
scrape_region_constraints(infcx, root_def_id, "fully_perform", span, |ocx| {
let (output, ei, obligations, _) =
let (output, ei, obligations) =
Q::fully_perform_into(self, infcx, &mut region_constraints, span)?;
error_info = ei;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0283]: type annotations needed: cannot satisfy `dyn D<&(), &()>: B<&()>`
--> $DIR/ambiguity-due-to-uniquification-1.rs:15:31
|
LL | (&() as &dyn D<&(), &()>).f()
| ^
|
= note: cannot satisfy `dyn D<&(), &()>: B<&()>`
help: the trait `B<C>` is implemented for `()`
--> $DIR/ambiguity-due-to-uniquification-1.rs:9:1
|
LL | impl<C> B<C> for () {}
| ^^^^^^^^^^^^^^^^^^^
note: required by a bound in `D::f`
--> $DIR/ambiguity-due-to-uniquification-1.rs:10:16
|
LL | trait D<C, E>: B<C> + B<E> {
| ^^^^ required by this bound in `D::f`
LL | fn f(&self) {}
|

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)
//@ check-pass
//@[current] check-pass

// Regression test for #139409 and trait-system-refactor-initiative#27.

Expand All @@ -13,4 +13,5 @@ trait D<C, E>: B<C> + B<E> {
impl<C, E> D<C, E> for () {}
fn main() {
(&() as &dyn D<&(), &()>).f()
//[next]~^ ERROR: type annotations needed: cannot satisfy `dyn D<&(), &()>: B<&()>`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0283]: type annotations needed: cannot satisfy `impl Trait<'_> + Trait<'_>: Trait<'_>`
--> $DIR/ambiguity-due-to-uniquification-2.rs:16:5
|
LL | impls_trait::<'y, _>(foo::<'x, 'y>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: cannot satisfy `impl Trait<'_> + Trait<'_>: Trait<'_>`
help: the trait `Trait<'t>` is implemented for `()`
--> $DIR/ambiguity-due-to-uniquification-2.rs:9:1
|
LL | impl<'t> Trait<'t> for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `impls_trait`
--> $DIR/ambiguity-due-to-uniquification-2.rs:13:23
|
LL | fn impls_trait<'x, T: Trait<'x>>(_: T) {}
| ^^^^^^^^^ required by this bound in `impls_trait`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)
//@ check-pass
//@[current] check-pass

// Regression test from trait-system-refactor-initiative#27.

Expand All @@ -14,6 +14,7 @@ fn impls_trait<'x, T: Trait<'x>>(_: T) {}

fn bar<'x, 'y>() {
impls_trait::<'y, _>(foo::<'x, 'y>());
//[next]~^ ERROR: type annotations needed: cannot satisfy `impl Trait<'_> + Trait<'_>: Trait<'_>`
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0283]: type annotations needed: cannot satisfy `dyn Object<&(), &()>: Trait<&()>`
--> $DIR/ambiguity-due-to-uniquification-3.rs:30:5
|
LL | impls_trait(obj, t);
| ^^^^^^^^^^^^^^^^^^^
|
= note: cannot satisfy `dyn Object<&(), &()>: Trait<&()>`
help: the trait `Trait<T>` is implemented for `()`
--> $DIR/ambiguity-due-to-uniquification-3.rs:17:1
|
LL | impl<T> Trait<T> for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `impls_trait`
--> $DIR/ambiguity-due-to-uniquification-3.rs:26:19
|
LL | fn impls_trait<T: Trait<U>, U>(_: Inv<T>, _: Inv<U>) {}
| ^^^^^^^^ required by this bound in `impls_trait`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)
//@ check-pass
//@[current] check-pass

// Regression test from trait-system-refactor-initiative#27.
//
Expand All @@ -28,6 +28,7 @@ fn impls_trait<T: Trait<U>, U>(_: Inv<T>, _: Inv<U>) {}
fn bar() {
let (obj, t) = foo();
impls_trait(obj, t);
//[next]~^ ERROR: type annotations needed: cannot satisfy `dyn Object<&(), &()>: Trait<&()>`
let _: Inv<dyn Object<&(), &()>> = obj;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0283]: type annotations needed: cannot satisfy `dyn D<&(), &()>: B<&()>`
--> $DIR/ambiguity-due-to-uniquification-old-solver.rs:15:31
|
LL | (&() as &dyn D<&(), &()>).f()
| ^
|
= note: cannot satisfy `dyn D<&(), &()>: B<&()>`
help: the trait `B<C>` is implemented for `()`
--> $DIR/ambiguity-due-to-uniquification-old-solver.rs:9:1
|
LL | impl<C> B<C> for () {}
| ^^^^^^^^^^^^^^^^^^^
note: required by a bound in `D::f`
--> $DIR/ambiguity-due-to-uniquification-old-solver.rs:10:16
|
LL | trait D<C, E>: B<C> + B<E> {
| ^^^^ required by this bound in `D::f`
LL | fn f(&self) {}
|

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[current] check-pass

// Regression test for #139409 and trait-system-refactor-initiative#27.

trait B<C> {}
impl<C> B<C> for () {}
trait D<C, E>: B<C> + B<E> {
fn f(&self) {}
}
impl<C, E> D<C, E> for () {}
fn main() {
(&() as &dyn D<&(), &()>).f()
//[next]~^ ERROR: type annotations needed: cannot satisfy `dyn D<&(), &()>: B<&()>`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0283]: type annotations needed: cannot satisfy `dyn Tr<'a, 'a, (), ()>: Sup<'a, ()>`
--> $DIR/ambiguity-due-to-uniquification-unsound-old.rs:38:7
|
LL | x.hide_me()
| ^^^^^^^
|
= note: cannot satisfy `dyn Tr<'a, 'a, (), ()>: Sup<'a, ()>`
help: the trait `Sup<'a, ()>` is implemented for `&'a str`
--> $DIR/ambiguity-due-to-uniquification-unsound-old.rs:16:1
|
LL | impl<'a> Sup<'a, ()> for &'a str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required for `dyn Tr<'a, 'a, (), ()>` to implement `HideMe`
--> $DIR/ambiguity-due-to-uniquification-unsound-old.rs:32:57
|
LL | impl<'a, T: Sup<'a, (), Assoc = &'static str> + ?Sized> HideMe for T {
| --------------------------------- ^^^^^^ ^
| |
| unsatisfied trait bound introduced here

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// A regression test for trait-system-refactor-initiative#307 affecting
// the old solver instead. The old solver only cares about region identity
// inside of `project` when merging candidates. This means this unsoundness
// also affects the old solver.

//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[current] failure-status: 101
//@[current] dont-check-compiler-stderr
//@[current] known-bug: unknown
trait Sup<'a, T> {
type Assoc;
fn to_assoc(&self) -> Self::Assoc;
}
impl<'a> Sup<'a, ()> for &'a str {
type Assoc = &'a str;
fn to_assoc(&self) -> Self::Assoc { self }
}

// Need the trait arguments to pass WF-checking
trait Tr<'a, 'b, T, U>: Sup<'a, T, Assoc = &'a str> + Sup<'b, U, Assoc = &'b str> {}
impl<'a> Tr<'a, 'a, (), ()> for &'a str {}

trait HideMe {
fn hide_me(&self) -> &'static str;
}

// Need the ambiguous `T: Sup<'a, (), Assoc = &'static str>` bound to only be
// used inside of the trait impl, as otherwise we also encounter ambiguity
// during normalization, which ICEs instead of ignoring it.
impl<'a, T: Sup<'a, (), Assoc = &'static str> + ?Sized> HideMe for T {
fn hide_me(&self) -> &'static str {
self.to_assoc()
}
}
fn yeet<'a>(x: &dyn Tr<'a, 'a, (), ()>) -> &'static str {
x.hide_me()
//[next]~^ ERROR: type annotations needed: cannot satisfy `dyn Tr<'a, 'a, (), ()>: Sup<'a, ()>`
}

fn main() {
let s = String::from("hello");
let r = yeet(&s.as_str());
drop(s);
println!("{r}");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0283]: type annotations needed: cannot satisfy `Self: Tr<'a>`
--> $DIR/ambiguity-due-to-uniquification-unsoundness.rs:12:18
|
LL | trait D<'a, 'b>: Tr<'a> + Tr<'b> {}
| ^^^^^^
|
note: multiple `impl`s or `where` clauses satisfying `Self: Tr<'a>` found
--> $DIR/ambiguity-due-to-uniquification-unsoundness.rs:12:18
|
LL | trait D<'a, 'b>: Tr<'a> + Tr<'b> {}
| ^^^^^^ ^^^^^^

error: lifetime may not live long enough
--> $DIR/ambiguity-due-to-uniquification-unsoundness.rs:18:47
|
LL | fn f<'a>(x: &dyn D<'a, 'a>) -> &'static str { x.get() }
| -- lifetime `'a` defined here ^^^^^^^ returning this value requires that `'a` must outlive `'static`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0283`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error[E0283]: type annotations needed: cannot satisfy `dyn D<'_, '_>: Tr<'_>`
--> $DIR/ambiguity-due-to-uniquification-unsoundness.rs:18:49
|
LL | fn f<'a>(x: &dyn D<'a, 'a>) -> &'static str { x.get() }
| ^^^
|
= note: cannot satisfy `dyn D<'_, '_>: Tr<'_>`
help: the trait `Tr<'t>` is implemented for `&'t str`
--> $DIR/ambiguity-due-to-uniquification-unsoundness.rs:15:1
|
LL | impl<'t> Tr<'t> for &'t str { fn get(&self) -> &'t str { *self } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// A regression test for trait-system-refactor-initiative#307. Proving
// `dyn D<'a, 'a>: Tr<'whatever>` passed in HIR typeck, but after
// uniquification proving `dyn D<'x, 'y>: Tr<'z>` in MIR borrowck
// failed with ambiguity. We incorrectly ignored this ambiguous result
// without registering any constraints, causing `f` to compile.

//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)

trait Tr<'t> { fn get(&self) -> &'t str; }
trait D<'a, 'b>: Tr<'a> + Tr<'b> {}
//[current]~^ ERROR: type annotations needed: cannot satisfy `Self: Tr<'a>`

impl<'t> Tr<'t> for &'t str { fn get(&self) -> &'t str { *self } }
impl<'a> D<'a, 'a> for &'a str {}

fn f<'a>(x: &dyn D<'a, 'a>) -> &'static str { x.get() }
//[current]~^ ERROR: lifetime may not live long enough
//[next]~^^ ERROR: type annotations needed: cannot satisfy `dyn D<'_, '_>: Tr<'_>`

fn main() {
let b = String::from("hi");
let r: &'static str = f(&b.as_str());
drop(b);
println!("{r}");
}
13 changes: 13 additions & 0 deletions tests/ui/traits/next-solver/unsize-goal-mismatch-2.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error[E0283]: type annotations needed: cannot satisfy `dyn Trait<&()>: Unsize<dyn Super<&()>>`
--> $DIR/unsize-goal-mismatch-2.rs:15:5
|
LL | x
| ^
|
= note: cannot satisfy `dyn Trait<&()>: Unsize<dyn Super<&()>>`
= note: required for `Box<dyn Trait<&()>>` to implement `CoerceUnsized<Box<dyn Super<&()>>>`
= note: required for the cast from `Box<(dyn Trait<&'a ()> + 'static)>` to `Box<(dyn Super<&'a ()> + 'static)>`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
3 changes: 2 additions & 1 deletion tests/ui/traits/next-solver/unsize-goal-mismatch-2.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
//@ check-pass
//@[current] check-pass
// Test from trait-system-refactor-initiative#241:
// Used to ICE in mir typeck because of ambiguity in the new solver.
// The wrong (first) trait bound was selected.
Expand All @@ -13,6 +13,7 @@ trait Trait<T>: Super<T> + for<'hr> Super<&'hr ()> {}

fn foo<'a>(x: Box<dyn Trait<&'a ()>>) -> Box<dyn Super<&'a ()>> {
x
//[next]~^ ERROR: type annotations needed: cannot satisfy `dyn Trait<&()>: Unsize<dyn Super<&()>>`
}

fn main() {}
Loading
Loading