Skip to content

Commit 1cbbc83

Browse files
committed
add tests
1 parent 4b315b0 commit 1cbbc83

7 files changed

+151
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ revisions: current next
2+
//@ ignore-compare-mode-next-solver (explicit revisions)
3+
//@[next] compile-flags: -Znext-solver
4+
//@ check-pass
5+
6+
// This caused a regression in a crater run in #132325.
7+
//
8+
// The underlying issue is a really subtle implementation detail.
9+
//
10+
// When building the `param_env` for `Trait` we start out with its
11+
// explicit predicates `Self: Trait` and `Self: for<'a> Super<'a, { 1 + 1 }>`.
12+
//
13+
// When normalizing the environment we also elaborate. This implicitly
14+
// deduplicates its returned predicates. We currently first eagerly
15+
// normalize constants in the unnormalized param env to avoid issues
16+
// caused by our lack of deferred alias equality.
17+
//
18+
// So we actually elaborate `Self: Trait` and `Self: for<'a> Super<'a, 2>`,
19+
// resulting in a third `Self: for<'a> Super<'a, { 1 + 1 }>` predicate which
20+
// then gets normalized to `Self: for<'a> Super<'a, 2>` at which point we
21+
// do not deduplicate however. By failing to handle equal where-bounds in
22+
// candidate selection, this caused ambiguity when checking that `Trait` is
23+
// well-formed.
24+
trait Super<'a, const N: usize> {}
25+
trait Trait: for<'a> Super<'a, { 1 + 1 }> {}
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ revisions: current next
2+
//@ ignore-compare-mode-next-solver (explicit revisions)
3+
//@[next] compile-flags: -Znext-solver
4+
//@ check-pass
5+
6+
// A regression test for an edge case of candidate selection
7+
// in the old trait solver, see #132325 for more details.
8+
9+
trait Trait<T> {}
10+
impl<T> Trait<T> for () {}
11+
12+
fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
13+
fn foo<T>() -> u32
14+
where
15+
(): Trait<u32>,
16+
(): Trait<T>,
17+
{
18+
impls_trait(())
19+
}
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/global-non-global-env-2.rs:20:5
3+
|
4+
LL | fn foo<T>() -> u32
5+
| - --- expected `u32` because of return type
6+
| |
7+
| found this type parameter
8+
...
9+
LL | impls_trait(())
10+
| ^^^^^^^^^^^^^^^ expected `u32`, found type parameter `T`
11+
|
12+
= note: expected type `u32`
13+
found type parameter `T`
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// A regression test for an edge case of candidate selection
2+
// in the old trait solver, see #132325 for more details. Unlike
3+
// the first test, this one has two impl candidates.
4+
5+
//@ revisions: current next
6+
//@ ignore-compare-mode-next-solver (explicit revisions)
7+
//@[next] compile-flags: -Znext-solver
8+
//@[next] check-pass
9+
10+
trait Trait<T> {}
11+
impl Trait<u32> for () {}
12+
impl Trait<u64> for () {}
13+
14+
fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
15+
fn foo<T>() -> u32
16+
where
17+
(): Trait<u32>,
18+
(): Trait<T>,
19+
{
20+
impls_trait(()) //[current]~ ERROR mismatched types
21+
}
22+
23+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//@ revisions: current next
2+
//@ ignore-compare-mode-next-solver (explicit revisions)
3+
//@[next] compile-flags: -Znext-solver
4+
//@ check-pass
5+
6+
// A regression test for an edge case of candidate selection
7+
// in the old trait solver, see #132325 for more details. Unlike
8+
// the second test, the where-bounds are in a different order.
9+
10+
trait Trait<T> {}
11+
impl Trait<u32> for () {}
12+
impl Trait<u64> for () {}
13+
14+
fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
15+
fn foo<T>() -> u32
16+
where
17+
(): Trait<T>,
18+
(): Trait<u32>,
19+
{
20+
impls_trait(())
21+
}
22+
23+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/global-non-global-env-4.rs:21:5
3+
|
4+
LL | fn foo<T>() -> u32
5+
| - --- expected `u32` because of return type
6+
| |
7+
| found this type parameter
8+
...
9+
LL | impls_trait(())
10+
| ^^^^^^^^^^^^^^^ expected `u32`, found type parameter `T`
11+
|
12+
= note: expected type `u32`
13+
found type parameter `T`
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// A regression test for an edge case of candidate selection
2+
// in the old trait solver, see #132325 for more details. Unlike
3+
// the third test, this one has 3 impl candidates.
4+
5+
//@ revisions: current next
6+
//@ ignore-compare-mode-next-solver (explicit revisions)
7+
//@[next] compile-flags: -Znext-solver
8+
//@[next] check-pass
9+
10+
trait Trait<T> {}
11+
impl Trait<u32> for () {}
12+
impl Trait<u64> for () {}
13+
impl Trait<u128> for () {}
14+
15+
fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
16+
fn foo<T>() -> u32
17+
where
18+
(): Trait<T>,
19+
(): Trait<u32>,
20+
{
21+
impls_trait(()) //[current]~ ERROR mismatched types
22+
}
23+
24+
fn main() {}

0 commit comments

Comments
 (0)