2023-08-17 08:15:09 -05:00
|
|
|
// compile-flags: -Ztrait-solver=next
|
2023-08-18 16:59:49 -05:00
|
|
|
// known-bug: trait-system-refactor-initiative#60
|
2023-08-17 08:15:09 -05:00
|
|
|
|
|
|
|
// Generalizing a projection containing an inference variable
|
|
|
|
// which cannot be named by the `root_vid` can result in ambiguity.
|
|
|
|
//
|
|
|
|
// Because we do not decrement the universe index when exiting a forall,
|
|
|
|
// this can cause unexpected failures.
|
|
|
|
//
|
|
|
|
// See generalize-proj-new-universe-index-1.rs for more details.
|
|
|
|
|
|
|
|
// For this reproduction we need:
|
|
|
|
// - an inference variable with a lower universe
|
|
|
|
// - enter a binder to increment the current universe
|
|
|
|
// - create a new inference variable which is constrained by proving a goal
|
|
|
|
// - equate a projection containing the new variable with the first variable
|
|
|
|
// - generalization creates yet another inference variable which is then
|
|
|
|
// part of an alias-relate, resulting this to fail with ambiguity.
|
|
|
|
//
|
|
|
|
// Because we need to enter the binder in-between the creation of the first
|
|
|
|
// and second inference variable, this is easiest via
|
|
|
|
// `assemble_candidates_after_normalizing_self_ty` because eagerly call
|
|
|
|
// `try_evaluate_added_goals` there before creating the inference variables
|
|
|
|
// for the impl parameters.
|
|
|
|
trait Id {
|
|
|
|
type Assoc: ?Sized;
|
|
|
|
}
|
|
|
|
impl<T: ?Sized> Id for T {
|
|
|
|
type Assoc = T;
|
|
|
|
}
|
|
|
|
|
|
|
|
// By adding an higher ranked bound to the impl we currently
|
|
|
|
// propagate this bound to the caller, forcing us to create a new
|
|
|
|
// universe.
|
|
|
|
trait IdHigherRankedBound {
|
|
|
|
type Assoc: ?Sized;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ?Sized> IdHigherRankedBound for T
|
|
|
|
where
|
|
|
|
for<'a> T: 'a,
|
|
|
|
{
|
|
|
|
type Assoc = T;
|
|
|
|
}
|
|
|
|
|
|
|
|
trait WithAssoc<T: ?Sized> {
|
|
|
|
type Assoc: ?Sized;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct Leaf;
|
|
|
|
struct Wrapper<U: ?Sized>(U);
|
|
|
|
struct Rigid;
|
|
|
|
|
|
|
|
impl<U: ?Sized> WithAssoc<U> for Leaf {
|
|
|
|
type Assoc = U;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<Ur: ?Sized> WithAssoc<Wrapper<Ur>> for Rigid
|
|
|
|
where
|
|
|
|
Leaf: WithAssoc<Ur>,
|
|
|
|
{
|
|
|
|
type Assoc = <<Leaf as WithAssoc<Ur>>::Assoc as Id>::Assoc;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
|
|
|
|
where
|
|
|
|
T: WithAssoc<U, Assoc = V>,
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
|
|
|
|
}
|