instantiate response: no unnecessary new universe
this previously was a off-by-one error.
This commit is contained in:
parent
d06ca0ffaf
commit
11716830ac
4 changed files with 158 additions and 1 deletions
|
@ -215,7 +215,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
// created inside of the query directly instead of returning them to the
|
||||
// caller.
|
||||
let prev_universe = self.infcx.universe();
|
||||
let universes_created_in_query = response.max_universe.index() + 1;
|
||||
let universes_created_in_query = response.max_universe.index();
|
||||
for _ in 0..universes_created_in_query {
|
||||
self.infcx.create_next_universe();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
// compile-flags: -Ztrait-solver=next
|
||||
// check-pass
|
||||
|
||||
// A minimization of an ambiguity when using typenum. See
|
||||
// https://github.com/rust-lang/trait-system-refactor-initiative/issues/55
|
||||
// for more details.
|
||||
trait Id {
|
||||
type Assoc: ?Sized;
|
||||
}
|
||||
impl<T: ?Sized> Id for T {
|
||||
type Assoc = T;
|
||||
}
|
||||
|
||||
trait WithAssoc<T: ?Sized> {
|
||||
type Assoc: ?Sized;
|
||||
}
|
||||
|
||||
|
||||
struct Leaf;
|
||||
struct Wrapper<U: ?Sized>(U);
|
||||
|
||||
impl<U: ?Sized> WithAssoc<U> for Leaf {
|
||||
type Assoc = U;
|
||||
}
|
||||
|
||||
impl<Ul: ?Sized, Ur: ?Sized> WithAssoc<Wrapper<Ur>> for Wrapper<Ul>
|
||||
where
|
||||
Ul: WithAssoc<Ur>,
|
||||
{
|
||||
type Assoc = <<Ul as WithAssoc<Ur>>::Assoc as Id>::Assoc;
|
||||
}
|
||||
|
||||
fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
|
||||
where
|
||||
T: WithAssoc<U, Assoc = V>,
|
||||
{
|
||||
}
|
||||
|
||||
// normalize self type to `Wrapper<Leaf>`
|
||||
// This succeeds, HOWEVER, instantiating the query response previously
|
||||
// incremented the universe index counter.
|
||||
// equate impl headers:
|
||||
// <Wrapper<Leaf> as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>
|
||||
// <Wrapper<?2t> as WithAssoc<Wrapper<?3t>>>
|
||||
// ~> AliasRelate(<Wrapper<Leaf> as Id>::Assoc, Equate, Wrapper<?3t>)
|
||||
// add where bounds:
|
||||
// ~> Leaf: WithAssoc<?3t>
|
||||
// equate with assoc type:
|
||||
// ?0t
|
||||
// <Leaf as WithAssoc<?3t>>::Assoc as Id>::Assoc
|
||||
// ~> AliasRelate(
|
||||
// <<Leaf as WithAssoc<?3t>>::Assoc as Id>::Assoc,
|
||||
// Equate,
|
||||
// <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc,
|
||||
// )
|
||||
//
|
||||
// We do not reuse `?3t` during generalization because `?0t` cannot name `?4t` as we created
|
||||
// it after incrementing the universe index while normalizing the self type.
|
||||
//
|
||||
// evaluate_added_goals_and_make_query_response:
|
||||
// AliasRelate(<Wrapper<Leaf> as Id>::Assoc, Equate, Wrapper<?3t>)
|
||||
// YES, constrains ?3t to Leaf
|
||||
// AliasRelate(
|
||||
// <<Leaf as WithAssoc<Leaf>>::Assoc as Id>::Assoc,
|
||||
// Equate,
|
||||
// <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc,
|
||||
// )
|
||||
//
|
||||
// Normalizing <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc then *correctly*
|
||||
// results in ambiguity.
|
||||
fn main() {
|
||||
bound::<<Wrapper<Leaf> as Id>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
// compile-flags: -Ztrait-solver=next
|
||||
|
||||
// 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, _>()
|
||||
//~^ ERROR type annotations needed
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
error[E0282]: type annotations needed
|
||||
--> $DIR/generalize-proj-new-universe-index-2.rs:72:5
|
||||
|
|
||||
LL | bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
Loading…
Add table
Add a link
Reference in a new issue