Skip to content

Commit 5f54889

Browse files
committed
add tests
1 parent 978c659 commit 5f54889

7 files changed

+132
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//@ check-pass
2+
3+
// This caused a regression in a crater run in #132325.
4+
//
5+
// The underlying issue is a really subtle implementation detail.
6+
//
7+
// When building the `param_env` for `Trait` we start out with its
8+
// explicit predicates `Self: Trait` and `Self: for<'a> Super<'a, { 1 + 1 }>`.
9+
//
10+
// When normalizing the environment we also elaborate. This implicitly
11+
// deduplicates its returned predicates. We currently first eagerly
12+
// normalize constants in the unnormalized param env to avoid issues
13+
// caused by our lack of deferred alias equality.
14+
//
15+
// So we actually elaborate `Self: Trait` and `Self: for<'a> Super<'a, 2>`,
16+
// resulting in a third `Self: for<'a> Super<'a, { 1 + 1 }>` predicate which
17+
// then gets normalized to `Self: for<'a> Super<'a, 2>` at which point we
18+
// do not deduplicate however. By failing to handle equal where-bounds in
19+
// candidate selection, this caused ambiguity when checking that `Trait` is
20+
// well-formed.
21+
trait Super<'a, const N: usize> {}
22+
trait Trait: for<'a> Super<'a, { 1 + 1 }> {}
23+
fn main() {}

Diff for: tests/ui/traits/winnowing/global-non-global-env-1.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ check-pass
2+
3+
// A regression test for an edge case of candidate selection
4+
// in the old trait solver, see #132325 for more details.
5+
6+
trait Trait<T> {}
7+
impl<T> Trait<T> for () {}
8+
9+
fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
10+
fn foo<T>() -> u32
11+
where
12+
(): Trait<u32>,
13+
(): Trait<T>,
14+
{
15+
impls_trait(())
16+
}
17+
18+
fn main() {}

Diff for: tests/ui/traits/winnowing/global-non-global-env-2.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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+
trait Trait<T> {}
6+
impl Trait<u32> for () {}
7+
impl Trait<u64> for () {}
8+
9+
fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
10+
fn foo<T>() -> u32
11+
where
12+
(): Trait<u32>,
13+
(): Trait<T>,
14+
{
15+
impls_trait(()) //~ ERROR mismatched types
16+
}
17+
18+
fn main() {}
+17
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:15: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`.

Diff for: tests/ui/traits/winnowing/global-non-global-env-3.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//@ check-pass
2+
3+
// A regression test for an edge case of candidate selection
4+
// in the old trait solver, see #132325 for more details. Unlike
5+
// the second test, the where-bounds are in a different order.
6+
7+
trait Trait<T> {}
8+
impl Trait<u32> for () {}
9+
impl Trait<u64> for () {}
10+
11+
fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
12+
fn foo<T>() -> u32
13+
where
14+
(): Trait<T>,
15+
(): Trait<u32>,
16+
{
17+
impls_trait(())
18+
}
19+
20+
fn main() {}

Diff for: tests/ui/traits/winnowing/global-non-global-env-4.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
trait Trait<T> {}
6+
impl Trait<u32> for () {}
7+
impl Trait<u64> for () {}
8+
impl Trait<u128> for () {}
9+
10+
fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
11+
fn foo<T>() -> u32
12+
where
13+
(): Trait<T>,
14+
(): Trait<u32>,
15+
{
16+
impls_trait(()) //~ ERROR mismatched types
17+
}
18+
19+
fn main() {}
+17
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:16: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`.

0 commit comments

Comments
 (0)