diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /tests/ui/traits/next-solver/generalize | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/traits/next-solver/generalize')
5 files changed, 216 insertions, 0 deletions
diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs new file mode 100644 index 000000000..4a70bd5f8 --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs @@ -0,0 +1,73 @@ +// compile-flags: -Znext-solver +// 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, _>() +} diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs new file mode 100644 index 000000000..70758e7de --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs @@ -0,0 +1,75 @@ +// compile-flags: -Znext-solver +// known-bug: trait-system-refactor-initiative#60 + +// 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, _>() +} diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr new file mode 100644 index 000000000..4548ab1e2 --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr @@ -0,0 +1,19 @@ +error[E0284]: type annotations needed + --> $DIR/generalize-proj-new-universe-index-2.rs:74: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` + | + = note: cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc == _` +note: required by a bound in `bound` + --> $DIR/generalize-proj-new-universe-index-2.rs:69:21 + | +LL | fn bound<T: ?Sized, U: ?Sized, V: ?Sized>() + | ----- required by a bound in this function +LL | where +LL | T: WithAssoc<U, Assoc = V>, + | ^^^^^^^^^ required by this bound in `bound` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr new file mode 100644 index 000000000..ad8b24a39 --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow evaluating the requirement `<<T as Id<_>>::Id as Unnormalizable>::Assoc == _` + --> $DIR/occurs-check-nested-alias.rs:36:9 + | +LL | x = y; + | ^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`occurs_check_nested_alias`) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs new file mode 100644 index 000000000..e51508d68 --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs @@ -0,0 +1,38 @@ +// revisions: old next +//[old] check-pass + +// Currently always fails to generalize the outer alias, even if it +// is treated as rigid by `alias-relate`. +//[next] compile-flags: -Znext-solver +//[next] known-bug: trait-system-refactor-initiative#8 +#![crate_type = "lib"] +#![allow(unused)] +trait Unnormalizable { + type Assoc; +} + +trait Id<T> { + type Id; +} +impl<T, U> Id<T> for U { + type Id = U; +} + +struct Inv<T>(*mut T); + +fn unconstrained<T>() -> T { + todo!() +} + +fn create<T, U: Unnormalizable>( + x: &U, +) -> (Inv<T>, Inv<<<U as Id<T>>::Id as Unnormalizable>::Assoc>) { + todo!() +} + +fn foo<T: Unnormalizable>() { + let q = unconstrained(); + let (mut x, y) = create::<_, _>(&q); + x = y; + drop::<T>(q); +} |