Skip to content

Commit 35e1f41

Browse files
authored
Rollup merge of rust-lang#114934 - lcnr:generalize-substs-relate, r=compiler-errors
instantiate response: no unnecessary new universe this previously was a off-by-one error. fixes rust-lang/trait-system-refactor-initiative#55 r? ```@compiler-errors```
2 parents ae93c8d + ee04744 commit 35e1f41

File tree

4 files changed

+158
-1
lines changed

4 files changed

+158
-1
lines changed

compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
215215
// created inside of the query directly instead of returning them to the
216216
// caller.
217217
let prev_universe = self.infcx.universe();
218-
let universes_created_in_query = response.max_universe.index() + 1;
218+
let universes_created_in_query = response.max_universe.index();
219219
for _ in 0..universes_created_in_query {
220220
self.infcx.create_next_universe();
221221
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// check-pass
3+
4+
// A minimization of an ambiguity when using typenum. See
5+
// https://github.com/rust-lang/trait-system-refactor-initiative/issues/55
6+
// for more details.
7+
trait Id {
8+
type Assoc: ?Sized;
9+
}
10+
impl<T: ?Sized> Id for T {
11+
type Assoc = T;
12+
}
13+
14+
trait WithAssoc<T: ?Sized> {
15+
type Assoc: ?Sized;
16+
}
17+
18+
19+
struct Leaf;
20+
struct Wrapper<U: ?Sized>(U);
21+
22+
impl<U: ?Sized> WithAssoc<U> for Leaf {
23+
type Assoc = U;
24+
}
25+
26+
impl<Ul: ?Sized, Ur: ?Sized> WithAssoc<Wrapper<Ur>> for Wrapper<Ul>
27+
where
28+
Ul: WithAssoc<Ur>,
29+
{
30+
type Assoc = <<Ul as WithAssoc<Ur>>::Assoc as Id>::Assoc;
31+
}
32+
33+
fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
34+
where
35+
T: WithAssoc<U, Assoc = V>,
36+
{
37+
}
38+
39+
// normalize self type to `Wrapper<Leaf>`
40+
// This succeeds, HOWEVER, instantiating the query response previously
41+
// incremented the universe index counter.
42+
// equate impl headers:
43+
// <Wrapper<Leaf> as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>
44+
// <Wrapper<?2t> as WithAssoc<Wrapper<?3t>>>
45+
// ~> AliasRelate(<Wrapper<Leaf> as Id>::Assoc, Equate, Wrapper<?3t>)
46+
// add where bounds:
47+
// ~> Leaf: WithAssoc<?3t>
48+
// equate with assoc type:
49+
// ?0t
50+
// <Leaf as WithAssoc<?3t>>::Assoc as Id>::Assoc
51+
// ~> AliasRelate(
52+
// <<Leaf as WithAssoc<?3t>>::Assoc as Id>::Assoc,
53+
// Equate,
54+
// <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc,
55+
// )
56+
//
57+
// We do not reuse `?3t` during generalization because `?0t` cannot name `?4t` as we created
58+
// it after incrementing the universe index while normalizing the self type.
59+
//
60+
// evaluate_added_goals_and_make_query_response:
61+
// AliasRelate(<Wrapper<Leaf> as Id>::Assoc, Equate, Wrapper<?3t>)
62+
// YES, constrains ?3t to Leaf
63+
// AliasRelate(
64+
// <<Leaf as WithAssoc<Leaf>>::Assoc as Id>::Assoc,
65+
// Equate,
66+
// <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc,
67+
// )
68+
//
69+
// Normalizing <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc then *correctly*
70+
// results in ambiguity.
71+
fn main() {
72+
bound::<<Wrapper<Leaf> as Id>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// known-bug: trait-system-refactor-initiative#60
3+
4+
// Generalizing a projection containing an inference variable
5+
// which cannot be named by the `root_vid` can result in ambiguity.
6+
//
7+
// Because we do not decrement the universe index when exiting a forall,
8+
// this can cause unexpected failures.
9+
//
10+
// See generalize-proj-new-universe-index-1.rs for more details.
11+
12+
// For this reproduction we need:
13+
// - an inference variable with a lower universe
14+
// - enter a binder to increment the current universe
15+
// - create a new inference variable which is constrained by proving a goal
16+
// - equate a projection containing the new variable with the first variable
17+
// - generalization creates yet another inference variable which is then
18+
// part of an alias-relate, resulting this to fail with ambiguity.
19+
//
20+
// Because we need to enter the binder in-between the creation of the first
21+
// and second inference variable, this is easiest via
22+
// `assemble_candidates_after_normalizing_self_ty` because eagerly call
23+
// `try_evaluate_added_goals` there before creating the inference variables
24+
// for the impl parameters.
25+
trait Id {
26+
type Assoc: ?Sized;
27+
}
28+
impl<T: ?Sized> Id for T {
29+
type Assoc = T;
30+
}
31+
32+
// By adding an higher ranked bound to the impl we currently
33+
// propagate this bound to the caller, forcing us to create a new
34+
// universe.
35+
trait IdHigherRankedBound {
36+
type Assoc: ?Sized;
37+
}
38+
39+
impl<T: ?Sized> IdHigherRankedBound for T
40+
where
41+
for<'a> T: 'a,
42+
{
43+
type Assoc = T;
44+
}
45+
46+
trait WithAssoc<T: ?Sized> {
47+
type Assoc: ?Sized;
48+
}
49+
50+
51+
struct Leaf;
52+
struct Wrapper<U: ?Sized>(U);
53+
struct Rigid;
54+
55+
impl<U: ?Sized> WithAssoc<U> for Leaf {
56+
type Assoc = U;
57+
}
58+
59+
60+
impl<Ur: ?Sized> WithAssoc<Wrapper<Ur>> for Rigid
61+
where
62+
Leaf: WithAssoc<Ur>,
63+
{
64+
type Assoc = <<Leaf as WithAssoc<Ur>>::Assoc as Id>::Assoc;
65+
}
66+
67+
fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
68+
where
69+
T: WithAssoc<U, Assoc = V>,
70+
{
71+
}
72+
73+
fn main() {
74+
bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/generalize-proj-new-universe-index-2.rs:74:5
3+
|
4+
LL | bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)