diff options
Diffstat (limited to 'tests')
7 files changed, 132 insertions, 0 deletions
diff --git a/tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs b/tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs new file mode 100644 index 00000000000..9600b3875ba --- /dev/null +++ b/tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs @@ -0,0 +1,23 @@ +//@ check-pass + +// This caused a regression in a crater run in #132325. +// +// The underlying issue is a really subtle implementation detail. +// +// When building the `param_env` for `Trait` we start out with its +// explicit predicates `Self: Trait` and `Self: for<'a> Super<'a, { 1 + 1 }>`. +// +// When normalizing the environment we also elaborate. This implicitly +// deduplicates its returned predicates. We currently first eagerly +// normalize constants in the unnormalized param env to avoid issues +// caused by our lack of deferred alias equality. +// +// So we actually elaborate `Self: Trait` and `Self: for<'a> Super<'a, 2>`, +// resulting in a third `Self: for<'a> Super<'a, { 1 + 1 }>` predicate which +// then gets normalized to `Self: for<'a> Super<'a, 2>` at which point we +// do not deduplicate however. By failing to handle equal where-bounds in +// candidate selection, this caused ambiguity when checking that `Trait` is +// well-formed. +trait Super<'a, const N: usize> {} +trait Trait: for<'a> Super<'a, { 1 + 1 }> {} +fn main() {} diff --git a/tests/ui/traits/winnowing/global-non-global-env-1.rs b/tests/ui/traits/winnowing/global-non-global-env-1.rs new file mode 100644 index 00000000000..d232d32dddf --- /dev/null +++ b/tests/ui/traits/winnowing/global-non-global-env-1.rs @@ -0,0 +1,18 @@ +//@ check-pass + +// A regression test for an edge case of candidate selection +// in the old trait solver, see #132325 for more details. + +trait Trait<T> {} +impl<T> Trait<T> for () {} + +fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() } +fn foo<T>() -> u32 +where + (): Trait<u32>, + (): Trait<T>, +{ + impls_trait(()) +} + +fn main() {} diff --git a/tests/ui/traits/winnowing/global-non-global-env-2.rs b/tests/ui/traits/winnowing/global-non-global-env-2.rs new file mode 100644 index 00000000000..16476069346 --- /dev/null +++ b/tests/ui/traits/winnowing/global-non-global-env-2.rs @@ -0,0 +1,18 @@ +// A regression test for an edge case of candidate selection +// in the old trait solver, see #132325 for more details. Unlike +// the first test, this one has two impl candidates. + +trait Trait<T> {} +impl Trait<u32> for () {} +impl Trait<u64> for () {} + +fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() } +fn foo<T>() -> u32 +where + (): Trait<u32>, + (): Trait<T>, +{ + impls_trait(()) //~ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/traits/winnowing/global-non-global-env-2.stderr b/tests/ui/traits/winnowing/global-non-global-env-2.stderr new file mode 100644 index 00000000000..dee01c72e48 --- /dev/null +++ b/tests/ui/traits/winnowing/global-non-global-env-2.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/global-non-global-env-2.rs:15:5 + | +LL | fn foo<T>() -> u32 + | - --- expected `u32` because of return type + | | + | found this type parameter +... +LL | impls_trait(()) + | ^^^^^^^^^^^^^^^ expected `u32`, found type parameter `T` + | + = note: expected type `u32` + found type parameter `T` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/winnowing/global-non-global-env-3.rs b/tests/ui/traits/winnowing/global-non-global-env-3.rs new file mode 100644 index 00000000000..008d07e4144 --- /dev/null +++ b/tests/ui/traits/winnowing/global-non-global-env-3.rs @@ -0,0 +1,20 @@ +//@ check-pass + +// A regression test for an edge case of candidate selection +// in the old trait solver, see #132325 for more details. Unlike +// the second test, the where-bounds are in a different order. + +trait Trait<T> {} +impl Trait<u32> for () {} +impl Trait<u64> for () {} + +fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() } +fn foo<T>() -> u32 +where + (): Trait<T>, + (): Trait<u32>, +{ + impls_trait(()) +} + +fn main() {} diff --git a/tests/ui/traits/winnowing/global-non-global-env-4.rs b/tests/ui/traits/winnowing/global-non-global-env-4.rs new file mode 100644 index 00000000000..1f35cf20f83 --- /dev/null +++ b/tests/ui/traits/winnowing/global-non-global-env-4.rs @@ -0,0 +1,19 @@ +// A regression test for an edge case of candidate selection +// in the old trait solver, see #132325 for more details. Unlike +// the third test, this one has 3 impl candidates. + +trait Trait<T> {} +impl Trait<u32> for () {} +impl Trait<u64> for () {} +impl Trait<u128> for () {} + +fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() } +fn foo<T>() -> u32 +where + (): Trait<T>, + (): Trait<u32>, +{ + impls_trait(()) //~ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/traits/winnowing/global-non-global-env-4.stderr b/tests/ui/traits/winnowing/global-non-global-env-4.stderr new file mode 100644 index 00000000000..6449f3feb08 --- /dev/null +++ b/tests/ui/traits/winnowing/global-non-global-env-4.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/global-non-global-env-4.rs:16:5 + | +LL | fn foo<T>() -> u32 + | - --- expected `u32` because of return type + | | + | found this type parameter +... +LL | impls_trait(()) + | ^^^^^^^^^^^^^^^ expected `u32`, found type parameter `T` + | + = note: expected type `u32` + found type parameter `T` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. |
