rust/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs
2024-04-03 22:48:55 +01:00

63 lines
2.4 KiB
Rust

//@ revisions: next current
//@[next] compile-flags: -Znext-solver
// cc #119820 the previous behavior here was inconsistent as we discarded
// 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
//[current]~^^ ERROR implementation of `Trait` is not general enough
}
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 implementation of `Trait` is not general enough
//[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 were 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() {}