mirror of https://github.com/rust-lang/rust
61 lines
2.3 KiB
Rust
61 lines
2.3 KiB
Rust
//@ revisions: next current
|
|
//@[next] compile-flags: -Znext-solver
|
|
|
|
// cc #119820 the behavior is inconsistent as we discard the where-bound
|
|
// candidate for trait goals due to the leak check, but did
|
|
// not do so for projection candidates and during normalization.
|
|
//
|
|
// This results in an inconsistency between `Trait` and `Projection` goals as
|
|
// normalizing always constraints the normalized-to term.
|
|
trait Trait<'a> {
|
|
type Assoc;
|
|
}
|
|
impl<'a, T> Trait<'a> for T {
|
|
type Assoc = usize;
|
|
}
|
|
|
|
fn trait_bound<T: for<'a> Trait<'a>>() {}
|
|
fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
|
|
|
|
// We use a function with a trivial where-bound which is more
|
|
// restrictive than the impl.
|
|
fn function1<T: Trait<'static>>() {
|
|
// err
|
|
//
|
|
// Proving `for<'a> T: Trait<'a>` using the where-bound does not
|
|
// result in a leak check failure even though it does not apply.
|
|
// We prefer env candidates over impl candidatescausing this to succeed.
|
|
trait_bound::<T>();
|
|
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
|
|
}
|
|
|
|
fn function2<T: Trait<'static, Assoc = usize>>() {
|
|
// err
|
|
//
|
|
// Proving the `Projection` goal `for<'a> T: Trait<'a, Assoc = usize>`
|
|
// does not use the leak check when trying the where-bound, causing us
|
|
// to prefer it over the impl, resulting in a placeholder error.
|
|
projection_bound::<T>();
|
|
//[next]~^ ERROR type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
|
|
//[next]~| ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
|
|
//[current]~^^^ ERROR mismatched types
|
|
}
|
|
|
|
fn function3<T: Trait<'static, Assoc = usize>>() {
|
|
// err
|
|
//
|
|
// Trying to normalize the type `for<'a> fn(<T as Trait<'a>>::Assoc)`
|
|
// only gets to `<T as Trait<'a>>::Assoc` once `'a` has been already
|
|
// instantiated, causing us to prefer the where-bound over the impl
|
|
// resulting in a placeholder error. Even if we were to also use the
|
|
// leak check during candidate selection for normalization, this
|
|
// case would still not compile.
|
|
let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
|
|
//[next]~^ ERROR higher-ranked subtype error
|
|
//[next]~| ERROR higher-ranked subtype error
|
|
//[current]~^^^ ERROR mismatched types
|
|
//[current]~| ERROR mismatched types
|
|
}
|
|
|
|
fn main() {}
|