summaryrefslogtreecommitdiffstats
path: root/tests/ui/traits
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/traits')
-rw-r--r--tests/ui/traits/dont-autoderef-ty-with-escaping-var.rs22
-rw-r--r--tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr27
-rw-r--r--tests/ui/traits/issue-105231.rs2
-rw-r--r--tests/ui/traits/issue-105231.stderr8
-rw-r--r--tests/ui/traits/issue-24010.rs2
-rw-r--r--tests/ui/traits/issue-91949-hangs-on-recursion.stderr3
-rw-r--r--tests/ui/traits/new-solver/alias-bound-preference.rs39
-rw-r--r--tests/ui/traits/new-solver/alias-bound-unsound.rs9
-rw-r--r--tests/ui/traits/new-solver/alias-bound-unsound.stderr65
-rw-r--r--tests/ui/traits/new-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs27
-rw-r--r--tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs (renamed from tests/ui/traits/new-solver/runaway-impl-candidate-selection.rs)0
-rw-r--r--tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr (renamed from tests/ui/traits/new-solver/runaway-impl-candidate-selection.stderr)0
-rw-r--r--tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs20
-rw-r--r--tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr12
-rw-r--r--tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs22
-rw-r--r--tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs25
-rw-r--r--tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs24
-rw-r--r--tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs32
-rw-r--r--tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr23
-rw-r--r--tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs69
-rw-r--r--tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr16
-rw-r--r--tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs37
-rw-r--r--tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr29
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs48
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr16
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs44
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs36
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs46
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr16
-rw-r--r--tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs (renamed from tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs)2
-rw-r--r--tests/ui/traits/new-solver/cycles/provisional-result-done.rs (renamed from tests/ui/traits/new-solver/provisional-result-done.rs)0
-rw-r--r--tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs17
-rw-r--r--tests/ui/traits/new-solver/dont-loop-fulfill-on-region-constraints.rs32
-rw-r--r--tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs22
-rw-r--r--tests/ui/traits/new-solver/dont-normalize-proj-with-error.stderr9
-rw-r--r--tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs4
-rw-r--r--tests/ui/traits/new-solver/escaping-bound-vars-in-writeback-normalization.rs18
-rw-r--r--tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs73
-rw-r--r--tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs75
-rw-r--r--tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr9
-rw-r--r--tests/ui/traits/new-solver/lazy-nested-obligations-2.rs2
-rw-r--r--tests/ui/traits/new-solver/lazy-nested-obligations-2.stderr39
-rw-r--r--tests/ui/traits/new-solver/more-object-bound.stderr4
-rw-r--r--tests/ui/traits/new-solver/normalize-unsize-rhs.rs23
-rw-r--r--tests/ui/traits/new-solver/object-soundness-requires-generalization.rs20
-rw-r--r--tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs (renamed from tests/ui/traits/new-solver/exponential-trait-goals.rs)0
-rw-r--r--tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr (renamed from tests/ui/traits/new-solver/exponential-trait-goals.stderr)0
-rw-r--r--tests/ui/traits/new-solver/overflow/global-cache.rs23
-rw-r--r--tests/ui/traits/new-solver/overflow/global-cache.stderr16
-rw-r--r--tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs (renamed from tests/ui/traits/new-solver/recursive-self-normalization-2.rs)0
-rw-r--r--tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr (renamed from tests/ui/traits/new-solver/recursive-self-normalization-2.stderr)0
-rw-r--r--tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs (renamed from tests/ui/traits/new-solver/recursive-self-normalization.rs)0
-rw-r--r--tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr (renamed from tests/ui/traits/new-solver/recursive-self-normalization.stderr)0
-rw-r--r--tests/ui/traits/new-solver/trait-upcast-lhs-needs-normalization.rs20
-rw-r--r--tests/ui/traits/new-solver/unsize-although-ambiguous.rs13
-rw-r--r--tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.rs19
-rw-r--r--tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.stderr11
-rw-r--r--tests/ui/traits/object/print_vtable_sizes.rs5
-rw-r--r--tests/ui/traits/object/print_vtable_sizes.stdout2
-rw-r--r--tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs2
-rw-r--r--tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr8
-rw-r--r--tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr1
-rw-r--r--tests/ui/traits/trait-upcasting/fewer-associated.rs25
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr14
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr14
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs23
-rw-r--r--tests/ui/traits/trait-upcasting/issue-11515.current.stderr13
-rw-r--r--tests/ui/traits/trait-upcasting/issue-11515.next.stderr13
-rw-r--r--tests/ui/traits/trait-upcasting/issue-11515.rs11
-rw-r--r--tests/ui/traits/trait-upcasting/normalization.rs20
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr9
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr9
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.rs4
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.stderr23
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-2.rs2
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-2.stderr37
-rw-r--r--tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr13
-rw-r--r--tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr13
-rw-r--r--tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs14
-rw-r--r--tests/ui/traits/vtable/multiple-markers.rs47
-rw-r--r--tests/ui/traits/vtable/multiple-markers.stderr52
81 files changed, 1425 insertions, 119 deletions
diff --git a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.rs b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.rs
new file mode 100644
index 000000000..d5ba3847a
--- /dev/null
+++ b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.rs
@@ -0,0 +1,22 @@
+// issue:113951
+
+trait Foo<'x, T> {}
+
+trait RefFoo<T> {
+ fn ref_foo(&self);
+}
+
+impl<T> RefFoo<T> for T
+where
+ for<'a> &'a mut Vec<&'a u32>: Foo<'static, T>,
+{
+ fn ref_foo(&self) {}
+}
+
+fn coerce_lifetime2() {
+ <i32 as RefFoo<i32>>::ref_foo(unknown);
+ //~^ ERROR cannot find value `unknown` in this scope
+ //~| ERROR the trait bound `for<'a> &'a mut Vec<&'a u32>: Foo<'static, i32>` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr
new file mode 100644
index 000000000..934d20b22
--- /dev/null
+++ b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr
@@ -0,0 +1,27 @@
+error[E0425]: cannot find value `unknown` in this scope
+ --> $DIR/dont-autoderef-ty-with-escaping-var.rs:17:35
+ |
+LL | <i32 as RefFoo<i32>>::ref_foo(unknown);
+ | ^^^^^^^ not found in this scope
+
+error[E0277]: the trait bound `for<'a> &'a mut Vec<&'a u32>: Foo<'static, i32>` is not satisfied
+ --> $DIR/dont-autoderef-ty-with-escaping-var.rs:17:35
+ |
+LL | <i32 as RefFoo<i32>>::ref_foo(unknown);
+ | ----------------------------- ^^^^^^^ the trait `for<'a> Foo<'static, i32>` is not implemented for `&'a mut Vec<&'a u32>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required for `i32` to implement `RefFoo<i32>`
+ --> $DIR/dont-autoderef-ty-with-escaping-var.rs:9:9
+ |
+LL | impl<T> RefFoo<T> for T
+ | ^^^^^^^^^ ^
+LL | where
+LL | for<'a> &'a mut Vec<&'a u32>: Foo<'static, T>,
+ | --------------- unsatisfied trait bound introduced here
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0425.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/issue-105231.rs b/tests/ui/traits/issue-105231.rs
index 74c7afd6b..bb2b13664 100644
--- a/tests/ui/traits/issue-105231.rs
+++ b/tests/ui/traits/issue-105231.rs
@@ -1,9 +1,9 @@
-//~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
struct A<T>(B<T>);
//~^ ERROR recursive types `A` and `B` have infinite size
struct B<T>(A<A<T>>);
trait Foo {}
impl<T> Foo for T where T: Send {}
+//~^ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
impl Foo for B<u8> {}
fn main() {}
diff --git a/tests/ui/traits/issue-105231.stderr b/tests/ui/traits/issue-105231.stderr
index fe20c47c5..76a710673 100644
--- a/tests/ui/traits/issue-105231.stderr
+++ b/tests/ui/traits/issue-105231.stderr
@@ -1,5 +1,5 @@
error[E0072]: recursive types `A` and `B` have infinite size
- --> $DIR/issue-105231.rs:2:1
+ --> $DIR/issue-105231.rs:1:1
|
LL | struct A<T>(B<T>);
| ^^^^^^^^^^^ ---- recursive without indirection
@@ -15,10 +15,14 @@ LL ~ struct B<T>(Box<A<A<T>>>);
|
error[E0275]: overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
+ --> $DIR/issue-105231.rs:5:28
+ |
+LL | impl<T> Foo for T where T: Send {}
+ | ^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`)
note: required because it appears within the type `B<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<u8>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
- --> $DIR/issue-105231.rs:4:8
+ --> $DIR/issue-105231.rs:3:8
|
LL | struct B<T>(A<A<T>>);
| ^
diff --git a/tests/ui/traits/issue-24010.rs b/tests/ui/traits/issue-24010.rs
index f18185334..fd7d6751d 100644
--- a/tests/ui/traits/issue-24010.rs
+++ b/tests/ui/traits/issue-24010.rs
@@ -1,4 +1,6 @@
// run-pass
+// revisions: classic next
+//[next] compile-flags: -Ztrait-solver=next
trait Foo: Fn(i32) -> i32 + Send {}
diff --git a/tests/ui/traits/issue-91949-hangs-on-recursion.stderr b/tests/ui/traits/issue-91949-hangs-on-recursion.stderr
index c721dd41a..c6fc7bb12 100644
--- a/tests/ui/traits/issue-91949-hangs-on-recursion.stderr
+++ b/tests/ui/traits/issue-91949-hangs-on-recursion.stderr
@@ -23,8 +23,7 @@ LL | impl<T, I: Iterator<Item = T>> Iterator for IteratorOfWrapped<T, I> {
| |
| unsatisfied trait bound introduced here
= note: 256 redundant requirements hidden
- = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<..., ...>>, ...>>, ...>>` to implement `Iterator`
- = note: the full type name has been written to '$TEST_BUILD_DIR/traits/issue-91949-hangs-on-recursion/issue-91949-hangs-on-recursion.long-type-hash.txt'
+ = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), std::iter::Empty<()>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48]>>` to implement `Iterator`
error: aborting due to previous error; 1 warning emitted
diff --git a/tests/ui/traits/new-solver/alias-bound-preference.rs b/tests/ui/traits/new-solver/alias-bound-preference.rs
new file mode 100644
index 000000000..e4e0f634e
--- /dev/null
+++ b/tests/ui/traits/new-solver/alias-bound-preference.rs
@@ -0,0 +1,39 @@
+// revisions: old next
+//[next] compile-flags: -Ztrait-solver=next
+// run-pass
+
+// A test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/45.
+
+trait Trait {
+ type Assoc: Into<u32>;
+}
+impl<T: Into<u32>> Trait for T {
+ type Assoc = T;
+}
+fn prefer_alias_bound_projection<T: Trait>(x: T::Assoc) {
+ // There are two possible types for `x`:
+ // - `u32` by using the "alias bound" of `<T as Trait>::Assoc`
+ // - `<T as Trait>::Assoc`, i.e. `u16`, by using `impl<T> From<T> for T`
+ //
+ // We infer the type of `x` to be `u32` here as it is highly likely
+ // that this is expected by the user.
+ let x = x.into();
+ assert_eq!(std::mem::size_of_val(&x), 4);
+}
+
+fn impl_trait() -> impl Into<u32> {
+ 0u16
+}
+
+fn main() {
+ // There are two possible types for `x`:
+ // - `u32` by using the "alias bound" of `impl Into<u32>`
+ // - `impl Into<u32>`, i.e. `u16`, by using `impl<T> From<T> for T`
+ //
+ // We infer the type of `x` to be `u32` here as it is highly likely
+ // that this is expected by the user.
+ let x = impl_trait().into();
+ assert_eq!(std::mem::size_of_val(&x), 4);
+
+ prefer_alias_bound_projection::<u16>(1);
+}
diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.rs b/tests/ui/traits/new-solver/alias-bound-unsound.rs
index 959f1afa0..38d83d289 100644
--- a/tests/ui/traits/new-solver/alias-bound-unsound.rs
+++ b/tests/ui/traits/new-solver/alias-bound-unsound.rs
@@ -16,12 +16,17 @@ trait Foo {
impl Foo for () {
type Item = String where String: Copy;
+ //~^ ERROR overflow evaluating the requirement `<() as Foo>::Item: Copy`
}
fn main() {
let x = String::from("hello, world");
drop(<() as Foo>::copy_me(&x));
- //~^ ERROR the type `&<() as Foo>::Item` is not well-formed
- //~| ERROR `<() as Foo>::Item` is not well-formed
+ //~^ ERROR overflow evaluating the requirement `<() as Foo>::Item: Sized`
+ //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
+ //~| ERROR overflow evaluating the requirement `<() as Foo>::Item well-formed`
+ //~| ERROR overflow evaluating the requirement `String <: <() as Foo>::Item`
+ //~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed`
+ //~| ERROR type annotations needed
println!("{x}");
}
diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.stderr b/tests/ui/traits/new-solver/alias-bound-unsound.stderr
index 5800e2c43..abc6677c1 100644
--- a/tests/ui/traits/new-solver/alias-bound-unsound.stderr
+++ b/tests/ui/traits/new-solver/alias-bound-unsound.stderr
@@ -1,14 +1,69 @@
-error: the type `&<() as Foo>::Item` is not well-formed
- --> $DIR/alias-bound-unsound.rs:23:31
+error[E0275]: overflow evaluating the requirement `<() as Foo>::Item: Copy`
+ --> $DIR/alias-bound-unsound.rs:18:17
+ |
+LL | type Item = String where String: Copy;
+ | ^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
+note: required by a bound in `Foo::Item`
+ --> $DIR/alias-bound-unsound.rs:8:16
+ |
+LL | type Item: Copy
+ | ^^^^ required by this bound in `Foo::Item`
+
+error[E0282]: type annotations needed
+ --> $DIR/alias-bound-unsound.rs:24:5
+ |
+LL | drop(<() as Foo>::copy_me(&x));
+ | ^^^^ cannot infer type of the type parameter `T` declared on the function `drop`
+ |
+help: consider specifying the generic argument
+ |
+LL | drop::<T>(<() as Foo>::copy_me(&x));
+ | +++++
+
+error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed`
+ --> $DIR/alias-bound-unsound.rs:24:31
|
LL | drop(<() as Foo>::copy_me(&x));
| ^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
-error: the type `<() as Foo>::Item` is not well-formed
- --> $DIR/alias-bound-unsound.rs:23:10
+error[E0275]: overflow evaluating the requirement `String <: <() as Foo>::Item`
+ --> $DIR/alias-bound-unsound.rs:24:31
+ |
+LL | drop(<() as Foo>::copy_me(&x));
+ | ^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
+
+error[E0275]: overflow evaluating the requirement `<() as Foo>::Item well-formed`
+ --> $DIR/alias-bound-unsound.rs:24:10
+ |
+LL | drop(<() as Foo>::copy_me(&x));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
+
+error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
+ --> $DIR/alias-bound-unsound.rs:24:10
|
LL | drop(<() as Foo>::copy_me(&x));
| ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
+
+error[E0275]: overflow evaluating the requirement `<() as Foo>::Item: Sized`
+ --> $DIR/alias-bound-unsound.rs:24:10
+ |
+LL | drop(<() as Foo>::copy_me(&x));
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
+ = note: the return type of a function must have a statically known size
-error: aborting due to 2 previous errors
+error: aborting due to 7 previous errors
+Some errors have detailed explanations: E0275, E0282.
+For more information about an error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/new-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs b/tests/ui/traits/new-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs
new file mode 100644
index 000000000..826e8c1e0
--- /dev/null
+++ b/tests/ui/traits/new-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs
@@ -0,0 +1,27 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+// Checks that we do not get ambiguity by considering an impl
+// multiple times if we're able to normalize the self type.
+
+trait Trait<'a> {}
+
+impl<'a, T: 'a> Trait<'a> for T {}
+
+fn impls_trait<'a, T: Trait<'a>>() {}
+
+trait Id {
+ type Assoc;
+}
+impl<T> Id for T {
+ type Assoc = T;
+}
+
+fn call<T>() {
+ impls_trait::<<T as Id>::Assoc>();
+}
+
+fn main() {
+ call::<()>();
+ impls_trait::<<<() as Id>::Assoc as Id>::Assoc>();
+}
diff --git a/tests/ui/traits/new-solver/runaway-impl-candidate-selection.rs b/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs
index 1dca86d36..1dca86d36 100644
--- a/tests/ui/traits/new-solver/runaway-impl-candidate-selection.rs
+++ b/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs
diff --git a/tests/ui/traits/new-solver/runaway-impl-candidate-selection.stderr b/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr
index 47004821a..47004821a 100644
--- a/tests/ui/traits/new-solver/runaway-impl-candidate-selection.stderr
+++ b/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
new file mode 100644
index 000000000..b39ae0333
--- /dev/null
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Ztrait-solver=next
+
+// Coherence should handle overflow while normalizing for
+// `trait_ref_is_knowable` correctly.
+
+trait Overflow {
+ type Assoc;
+}
+impl<T> Overflow for T {
+ type Assoc = <T as Overflow>::Assoc;
+}
+
+
+trait Trait {}
+impl<T: Copy> Trait for T {}
+struct LocalTy;
+impl Trait for <LocalTy as Overflow>::Assoc {}
+//~^ ERROR conflicting implementations of trait `Trait` for type `<LocalTy as Overflow>::Assoc`
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
new file mode 100644
index 000000000..5d5f325e4
--- /dev/null
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `<LocalTy as Overflow>::Assoc`
+ --> $DIR/trait_ref_is_knowable-norm-overflow.rs:17:1
+ |
+LL | impl<T: Copy> Trait for T {}
+ | ------------------------- first implementation here
+LL | struct LocalTy;
+LL | impl Trait for <LocalTy as Overflow>::Assoc {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<LocalTy as Overflow>::Assoc`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs
new file mode 100644
index 000000000..c38e3baf5
--- /dev/null
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs
@@ -0,0 +1,22 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+trait Id {
+ type Assoc;
+}
+impl<T> Id for T {
+ type Assoc = T;
+}
+
+
+// Coherence should be able to reason that `<LocalTy as Id>::Assoc: Copy`
+// does not hold.
+//
+// See https://github.com/rust-lang/trait-system-refactor-initiative/issues/51
+// for more details.
+trait Trait {}
+impl<T: Copy> Trait for T {}
+struct LocalTy;
+impl Trait for <LocalTy as Id>::Assoc {}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs
new file mode 100644
index 000000000..2d53266db
--- /dev/null
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs
@@ -0,0 +1,25 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+use std::future::{Future, IntoFuture};
+use std::pin::Pin;
+
+// We check that this does not overlap with the following impl from std:
+// impl<P> Future for Pin<P> where P: DerefMut, <P as Deref>::Target: Future { .. }
+// This should fail because we know ` <&mut Value as Deref>::Target: Future` not to hold.
+// For this to work we have to normalize in the `trait_ref_is_knowable` check as we
+// otherwise add an ambiguous candidate here.
+//
+// See https://github.com/rust-lang/trait-system-refactor-initiative/issues/51
+// for more details.
+struct Value;
+impl<'a> IntoFuture for Pin<&'a mut Value> {
+ type Output = ();
+ type IntoFuture = Pin<Box<dyn Future<Output = ()> + Send>>;
+
+ fn into_future(self) -> Self::IntoFuture {
+ todo!()
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs
new file mode 100644
index 000000000..2f27de4e4
--- /dev/null
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs
@@ -0,0 +1,24 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+trait Id {
+ type Assoc;
+}
+impl<T> Id for T {
+ type Assoc = T;
+}
+
+
+// Coherence should be able to reason that `(): PartialEq<<T as Id>::Assoc>>`
+// does not hold.
+//
+// See https://github.com/rust-lang/trait-system-refactor-initiative/issues/51
+// for more details.
+trait Trait {}
+impl<T> Trait for T
+where
+ (): PartialEq<T> {}
+struct LocalTy;
+impl Trait for <LocalTy as Id>::Assoc {}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs
new file mode 100644
index 000000000..fcafdcf63
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs
@@ -0,0 +1,32 @@
+// compile-flags: -Ztrait-solver=next
+
+// Proving `W<?0>: Trait` instantiates `?0` with `(W<?1>, W<?2>)` and then
+// proves `W<?1>: Trait` and `W<?2>: Trait`, resulting in a coinductive cycle.
+//
+// Proving coinductive cycles runs until we reach a fixpoint. This fixpoint is
+// never reached here and each step doubles the amount of nested obligations.
+//
+// This previously caused a hang in the trait solver, see
+// https://github.com/rust-lang/trait-system-refactor-initiative/issues/13.
+
+#![feature(rustc_attrs)]
+
+#[rustc_coinductive]
+trait Trait {}
+
+struct W<T>(T);
+
+impl<T, U> Trait for W<(W<T>, W<U>)>
+where
+ W<T>: Trait,
+ W<U>: Trait,
+{
+}
+
+fn impls<T: Trait>() {}
+
+fn main() {
+ impls::<W<_>>();
+ //~^ ERROR type annotations needed
+ //~| ERROR overflow evaluating the requirement
+}
diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
new file mode 100644
index 000000000..7d3535e1f
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
@@ -0,0 +1,23 @@
+error[E0282]: type annotations needed
+ --> $DIR/fixpoint-exponential-growth.rs:29:5
+ |
+LL | impls::<W<_>>();
+ | ^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls`
+
+error[E0275]: overflow evaluating the requirement `W<_>: Trait`
+ --> $DIR/fixpoint-exponential-growth.rs:29:5
+ |
+LL | impls::<W<_>>();
+ | ^^^^^^^^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`)
+note: required by a bound in `impls`
+ --> $DIR/fixpoint-exponential-growth.rs:26:13
+ |
+LL | fn impls<T: Trait>() {}
+ | ^^^^^ required by this bound in `impls`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0275, E0282.
+For more information about an error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs
new file mode 100644
index 000000000..0cd14f05c
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs
@@ -0,0 +1,69 @@
+// compile-flags: -Ztrait-solver=next
+#![feature(rustc_attrs)]
+
+// This test is incredibly subtle. At its core the goal is to get a coinductive cycle,
+// which, depending on its root goal, either holds or errors. We achieve this by getting
+// incomplete inference via a `ParamEnv` candidate in the `A<T>` impl and required
+// inference from an `Impl` candidate in the `B<T>` impl.
+//
+// To make global cache accesses stronger than the guidance from the where-bounds, we add
+// another coinductive cycle from `A<T>: Trait<U, V, D>` to `A<T>: Trait<U, D, V>` and only
+// constrain `D` directly. This means that any candidates which rely on `V` only make
+// progress in the second iteration, allowing a cache access in the first iteration to take
+// precedence.
+//
+// tl;dr: our caching of coinductive cycles was broken and this is a regression
+// test for that.
+
+#[rustc_coinductive]
+trait Trait<T: ?Sized, V: ?Sized, D: ?Sized> {}
+struct A<T: ?Sized>(*const T);
+struct B<T: ?Sized>(*const T);
+
+trait IncompleteGuidance<T: ?Sized, V: ?Sized> {}
+impl<T: ?Sized, U: ?Sized + 'static> IncompleteGuidance<U, u8> for T {}
+impl<T: ?Sized, U: ?Sized + 'static> IncompleteGuidance<U, i8> for T {}
+impl<T: ?Sized, U: ?Sized + 'static> IncompleteGuidance<U, i16> for T {}
+
+trait ImplGuidance<T: ?Sized, V: ?Sized> {}
+impl<T: ?Sized> ImplGuidance<u32, u8> for T {}
+impl<T: ?Sized> ImplGuidance<i32, i8> for T {}
+
+impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for A<T>
+where
+ T: IncompleteGuidance<U, V>,
+ A<T>: Trait<U, D, V>,
+ B<T>: Trait<U, V, D>,
+ (): ToU8<D>,
+{
+}
+
+trait ToU8<T: ?Sized> {}
+impl ToU8<u8> for () {}
+
+impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for B<T>
+where
+ T: ImplGuidance<U, V>,
+ A<T>: Trait<U, V, D>,
+{
+}
+
+fn impls_trait<T: ?Sized + Trait<U, V, D>, U: ?Sized, V: ?Sized, D: ?Sized>() {}
+
+fn with_bound<X>()
+where
+ X: IncompleteGuidance<i32, u8>,
+ X: IncompleteGuidance<u32, i8>,
+ X: IncompleteGuidance<u32, i16>,
+{
+ impls_trait::<B<X>, _, _, _>(); // entering the cycle from `B` works
+
+ // entering the cycle from `A` fails, but would work if we were to use the cache
+ // result of `B<X>`.
+ impls_trait::<A<X>, _, _, _>();
+ //~^ ERROR the trait bound `A<X>: Trait<_, _, _>` is not satisfied
+}
+
+fn main() {
+ with_bound::<u32>();
+}
diff --git a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr b/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr
new file mode 100644
index 000000000..f1871ff05
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied
+ --> $DIR/incompleteness-unstable-result.rs:63:19
+ |
+LL | impls_trait::<A<X>, _, _, _>();
+ | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>`
+ |
+ = help: the trait `Trait<U, V, D>` is implemented for `A<T>`
+note: required by a bound in `impls_trait`
+ --> $DIR/incompleteness-unstable-result.rs:51:28
+ |
+LL | fn impls_trait<T: ?Sized + Trait<U, V, D>, U: ?Sized, V: ?Sized, D: ?Sized>() {}
+ | ^^^^^^^^^^^^^^ required by this bound in `impls_trait`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs b/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs
new file mode 100644
index 000000000..5617e45ad
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs
@@ -0,0 +1,37 @@
+// compile-flags: -Ztrait-solver=next
+#![feature(rustc_attrs)]
+
+// Test that having both an inductive and a coinductive cycle
+// is handled correctly.
+
+#[rustc_coinductive]
+trait Trait {}
+impl<T: Inductive + Coinductive> Trait for T {}
+
+trait Inductive {}
+impl<T: Trait> Inductive for T {}
+#[rustc_coinductive]
+trait Coinductive {}
+impl<T: Trait> Coinductive for T {}
+
+fn impls_trait<T: Trait>() {}
+
+#[rustc_coinductive]
+trait TraitRev {}
+impl<T: CoinductiveRev + InductiveRev> TraitRev for T {}
+
+trait InductiveRev {}
+impl<T: TraitRev> InductiveRev for T {}
+#[rustc_coinductive]
+trait CoinductiveRev {}
+impl<T: TraitRev> CoinductiveRev for T {}
+
+fn impls_trait_rev<T: TraitRev>() {}
+
+fn main() {
+ impls_trait::<()>();
+ //~^ ERROR overflow evaluating the requirement
+
+ impls_trait_rev::<()>();
+ //~^ ERROR overflow evaluating the requirement
+}
diff --git a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr b/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr
new file mode 100644
index 000000000..4b8846da5
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr
@@ -0,0 +1,29 @@
+error[E0275]: overflow evaluating the requirement `(): Trait`
+ --> $DIR/double-cycle-inductive-coinductive.rs:32:5
+ |
+LL | impls_trait::<()>();
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
+note: required by a bound in `impls_trait`
+ --> $DIR/double-cycle-inductive-coinductive.rs:17:19
+ |
+LL | fn impls_trait<T: Trait>() {}
+ | ^^^^^ required by this bound in `impls_trait`
+
+error[E0275]: overflow evaluating the requirement `(): TraitRev`
+ --> $DIR/double-cycle-inductive-coinductive.rs:35:5
+ |
+LL | impls_trait_rev::<()>();
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
+note: required by a bound in `impls_trait_rev`
+ --> $DIR/double-cycle-inductive-coinductive.rs:29:23
+ |
+LL | fn impls_trait_rev<T: TraitRev>() {}
+ | ^^^^^^^^ required by this bound in `impls_trait_rev`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs
new file mode 100644
index 000000000..cda987898
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs
@@ -0,0 +1,48 @@
+// compile-flags: -Ztrait-solver=next
+#![feature(trivial_bounds, marker_trait_attr)]
+#![allow(trivial_bounds)]
+// This previously triggered a bug in the provisional cache.
+//
+// This has the proof tree
+// - `MultipleCandidates: Trait` proven via impl-one
+// - `MultipleNested: Trait` via impl
+// - `MultipleCandidates: Trait` (inductive cycle ~> OVERFLOW)
+// - `DoesNotImpl: Trait` (ERR)
+// - `MultipleCandidates: Trait` proven via impl-two
+// - `MultipleNested: Trait` (in provisional cache ~> OVERFLOW)
+//
+// We previously incorrectly treated the `MultipleCandidates: Trait` as
+// overflow because it was in the cache and reached via an inductive cycle.
+// It should be `NoSolution`.
+
+struct MultipleCandidates;
+struct MultipleNested;
+struct DoesNotImpl;
+
+#[marker]
+trait Trait {}
+
+// impl-one
+impl Trait for MultipleCandidates
+where
+ MultipleNested: Trait
+{}
+
+// impl-two
+impl Trait for MultipleCandidates
+where
+ MultipleNested: Trait,
+{}
+
+impl Trait for MultipleNested
+where
+ MultipleCandidates: Trait,
+ DoesNotImpl: Trait,
+{}
+
+fn impls_trait<T: Trait>() {}
+
+fn main() {
+ impls_trait::<MultipleCandidates>();
+ //~^ ERROR the trait bound `MultipleCandidates: Trait` is not satisfied
+}
diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr
new file mode 100644
index 000000000..57227321a
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `MultipleCandidates: Trait` is not satisfied
+ --> $DIR/inductive-cycle-but-err.rs:46:19
+ |
+LL | impls_trait::<MultipleCandidates>();
+ | ^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `MultipleCandidates`
+ |
+ = help: the trait `Trait` is implemented for `MultipleCandidates`
+note: required by a bound in `impls_trait`
+ --> $DIR/inductive-cycle-but-err.rs:43:19
+ |
+LL | fn impls_trait<T: Trait>() {}
+ | ^^^^^ required by this bound in `impls_trait`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs
new file mode 100644
index 000000000..d4851eb69
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs
@@ -0,0 +1,44 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+#![feature(trivial_bounds, marker_trait_attr)]
+#![allow(trivial_bounds)]
+
+// This previously triggered a bug in the provisional cache.
+//
+// This has the proof tree
+// - `Root: Trait` proven via impl
+// - `MultipleCandidates: Trait`
+// - candidate: overflow-impl
+// - `Root: Trait` (inductive cycle ~> OVERFLOW)
+// - candidate: trivial-impl ~> YES
+// - merge respones ~> YES
+// - `MultipleCandidates: Trait` (in provisional cache ~> OVERFLOW)
+//
+// We previously incorrectly treated the `MultipleCandidates: Trait` as
+// overflow because it was in the cache and reached via an inductive cycle.
+// It should be `YES`.
+
+struct Root;
+struct MultipleCandidates;
+
+#[marker]
+trait Trait {}
+impl Trait for Root
+where
+ MultipleCandidates: Trait,
+ MultipleCandidates: Trait,
+{}
+
+// overflow-impl
+impl Trait for MultipleCandidates
+where
+ Root: Trait,
+{}
+// trivial-impl
+impl Trait for MultipleCandidates {}
+
+fn impls_trait<T: Trait>() {}
+
+fn main() {
+ impls_trait::<Root>();
+}
diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs b/tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs
new file mode 100644
index 000000000..530e6d0ec
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs
@@ -0,0 +1,36 @@
+// check-pass
+// compile-flags: -Ztrait-solver=next
+#![feature(rustc_attrs, marker_trait_attr)]
+#[rustc_coinductive]
+trait Trait {}
+
+impl<T, U> Trait for (T, U)
+where
+ (U, T): Trait,
+ (T, U): Inductive,
+ (): ConstrainToU32<T>,
+{}
+
+trait ConstrainToU32<T> {}
+impl ConstrainToU32<u32> for () {}
+
+// We only prefer the candidate without an inductive cycle
+// once the inductive cycle has the same constraints as the
+// other goal.
+#[marker]
+trait Inductive {}
+impl<T, U> Inductive for (T, U)
+where
+ (T, U): Trait,
+{}
+
+impl Inductive for (u32, u32) {}
+
+fn impls_trait<T, U>()
+where
+ (T, U): Trait,
+{}
+
+fn main() {
+ impls_trait::<_, _>();
+}
diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs
new file mode 100644
index 000000000..3cfe7ab87
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs
@@ -0,0 +1,46 @@
+// compile-flags: -Ztrait-solver=next
+#![feature(rustc_attrs, trivial_bounds)]
+
+// We have to be careful here:
+//
+// We either have the provisional result of `A -> B -> A` on the
+// stack, which is a fully coinductive cycle. Accessing the
+// provisional result for `B` as part of the `A -> C -> B -> A` cycle
+// has to make sure we don't just use the result of `A -> B -> A` as the
+// new cycle is inductive.
+//
+// Alternatively, if we have `A -> C -> A` first, then `A -> B -> A` has
+// a purely inductive stack, so something could also go wrong here.
+
+#[rustc_coinductive]
+trait A {}
+#[rustc_coinductive]
+trait B {}
+trait C {}
+
+impl<T: B + C> A for T {}
+impl<T: A> B for T {}
+impl<T: B> C for T {}
+
+fn impls_a<T: A>() {}
+
+// The same test with reordered where clauses to make sure we're actually testing anything.
+#[rustc_coinductive]
+trait AR {}
+#[rustc_coinductive]
+trait BR {}
+trait CR {}
+
+impl<T: CR + BR> AR for T {}
+impl<T: AR> BR for T {}
+impl<T: BR> CR for T {}
+
+fn impls_ar<T: AR>() {}
+
+fn main() {
+ impls_a::<()>();
+ // FIXME(-Ztrait-solver=next): This is broken and should error.
+
+ impls_ar::<()>();
+ //~^ ERROR overflow evaluating the requirement `(): AR`
+}
diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr
new file mode 100644
index 000000000..0e1c86c1b
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr
@@ -0,0 +1,16 @@
+error[E0275]: overflow evaluating the requirement `(): AR`
+ --> $DIR/inductive-not-on-stack.rs:44:5
+ |
+LL | impls_ar::<()>();
+ | ^^^^^^^^^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
+note: required by a bound in `impls_ar`
+ --> $DIR/inductive-not-on-stack.rs:38:16
+ |
+LL | fn impls_ar<T: AR>() {}
+ | ^^ required by this bound in `impls_ar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs b/tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs
index 1f7d4a49c..a6d318726 100644
--- a/tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs
+++ b/tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs
@@ -1,5 +1,5 @@
-// check-pass
// compile-flags: -Ztrait-solver=next
+// check-pass
#![feature(rustc_attrs)]
#[rustc_coinductive]
diff --git a/tests/ui/traits/new-solver/provisional-result-done.rs b/tests/ui/traits/new-solver/cycles/provisional-result-done.rs
index 589d34dd7..589d34dd7 100644
--- a/tests/ui/traits/new-solver/provisional-result-done.rs
+++ b/tests/ui/traits/new-solver/cycles/provisional-result-done.rs
diff --git a/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs b/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs
new file mode 100644
index 000000000..c2ac80459
--- /dev/null
+++ b/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs
@@ -0,0 +1,17 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+use std::fmt::Display;
+use std::rc::Rc;
+
+fn mk<T: ?Sized>(t: Option<&T>) -> Rc<T> {
+ todo!()
+}
+
+fn main() {
+ let mut x = None;
+ let y = mk(x);
+ // Don't treat the line below as a unsize coercion `Rc<?0> ~> Rc<dyn Display>`
+ let z: Rc<dyn Display> = y;
+ x = Some(&1 as &dyn Display);
+}
diff --git a/tests/ui/traits/new-solver/dont-loop-fulfill-on-region-constraints.rs b/tests/ui/traits/new-solver/dont-loop-fulfill-on-region-constraints.rs
new file mode 100644
index 000000000..b241e3bf8
--- /dev/null
+++ b/tests/ui/traits/new-solver/dont-loop-fulfill-on-region-constraints.rs
@@ -0,0 +1,32 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+trait Eq<'a, 'b, T> {}
+
+trait Ambig {}
+impl Ambig for () {}
+
+impl<'a, T> Eq<'a, 'a, T> for () where T: Ambig {}
+
+fn eq<'a, 'b, T>(t: T)
+where
+ (): Eq<'a, 'b, T>,
+{
+}
+
+fn test<'r>() {
+ let mut x = Default::default();
+
+ // When we evaluate `(): Eq<'r, 'r, ?0>` we uniquify the regions.
+ // That leads us to evaluate `(): Eq<'?0, '?1, ?0>`. The response of this
+ // will be ambiguous (because `?0: Ambig` is ambig) and also not an "identity"
+ // response, since the region constraints will contain `'?0 == '?1` (so
+ // `is_changed` will return true). Since it's both ambig and changed,
+ // fulfillment will both re-register the goal AND loop again. This hits the
+ // overflow limit. This should neither be considered overflow, nor ICE.
+ eq::<'r, 'r, _>(x);
+
+ x = ();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs b/tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs
new file mode 100644
index 000000000..19a6fa990
--- /dev/null
+++ b/tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs
@@ -0,0 +1,22 @@
+// compile-flags: -Ztrait-solver=next
+
+// Test that we don't incorrectly leak unconstrained inference variables
+// if the projection contained an error. This caused an ICE in writeback.
+
+trait Mirror {
+ type Assoc: ?Sized;
+}
+
+struct Wrapper<T: ?Sized>(T);
+impl<T: ?Sized> Mirror for Wrapper<T> {
+ type Assoc = T;
+}
+
+fn mirror<W: Mirror>(_: W) -> Box<W::Assoc> { todo!() }
+
+fn type_error() -> TypeError { todo!() }
+//~^ ERROR cannot find type `TypeError` in this scope
+
+fn main() {
+ let x = mirror(type_error());
+}
diff --git a/tests/ui/traits/new-solver/dont-normalize-proj-with-error.stderr b/tests/ui/traits/new-solver/dont-normalize-proj-with-error.stderr
new file mode 100644
index 000000000..5a7459ec1
--- /dev/null
+++ b/tests/ui/traits/new-solver/dont-normalize-proj-with-error.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `TypeError` in this scope
+ --> $DIR/dont-normalize-proj-with-error.rs:17:20
+ |
+LL | fn type_error() -> TypeError { todo!() }
+ | ^^^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs b/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs
index 7d15b8c63..af35a6195 100644
--- a/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs
+++ b/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs
@@ -1,6 +1,10 @@
// compile-flags: -Ztrait-solver=next
// check-pass
+// Test that selection prefers the builtin trait object impl for `Any`
+// instead of the user defined impl. Both impls apply to the trait
+// object.
+
use std::any::Any;
fn needs_usize(_: &usize) {}
diff --git a/tests/ui/traits/new-solver/escaping-bound-vars-in-writeback-normalization.rs b/tests/ui/traits/new-solver/escaping-bound-vars-in-writeback-normalization.rs
new file mode 100644
index 000000000..29784c32a
--- /dev/null
+++ b/tests/ui/traits/new-solver/escaping-bound-vars-in-writeback-normalization.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+trait Trivial {
+ type Assoc;
+}
+
+impl<T: ?Sized> Trivial for T {
+ type Assoc = ();
+}
+
+fn main() {
+ // During writeback, we call `normalize_erasing_regions`, which will walk past
+ // the `for<'a>` binder and try to normalize `<&'a () as Trivial>::Assoc` directly.
+ // We need to handle this case in the new deep normalizer similarly to how it
+ // is handled in the old solver.
+ let x: Option<for<'a> fn(<&'a () as Trivial>::Assoc)> = None;
+}
diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs
new file mode 100644
index 000000000..b0b9b6bbd
--- /dev/null
+++ b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs
@@ -0,0 +1,73 @@
+// compile-flags: -Ztrait-solver=next
+// 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/new-solver/generalize/generalize-proj-new-universe-index-2.rs b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs
new file mode 100644
index 000000000..94d645a98
--- /dev/null
+++ b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs
@@ -0,0 +1,75 @@
+// compile-flags: -Ztrait-solver=next
+// 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/new-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr
new file mode 100644
index 000000000..9a8060133
--- /dev/null
+++ b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr
@@ -0,0 +1,9 @@
+error[E0282]: 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`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/traits/new-solver/lazy-nested-obligations-2.rs b/tests/ui/traits/new-solver/lazy-nested-obligations-2.rs
index fd91d81cd..20f504928 100644
--- a/tests/ui/traits/new-solver/lazy-nested-obligations-2.rs
+++ b/tests/ui/traits/new-solver/lazy-nested-obligations-2.rs
@@ -1,5 +1,5 @@
// compile-flags: -Ztrait-solver=next
-// known-bug: #95863
+// check-pass
pub trait With {
type F;
diff --git a/tests/ui/traits/new-solver/lazy-nested-obligations-2.stderr b/tests/ui/traits/new-solver/lazy-nested-obligations-2.stderr
deleted file mode 100644
index d0a4cd661..000000000
--- a/tests/ui/traits/new-solver/lazy-nested-obligations-2.stderr
+++ /dev/null
@@ -1,39 +0,0 @@
-error[E0308]: mismatched types
- --> $DIR/lazy-nested-obligations-2.rs:15:23
- |
-LL | let _: V<i32> = V(f);
- | - ^ types differ
- | |
- | arguments to this struct are incorrect
- |
- = note: expected associated type `<i32 as With>::F`
- found fn item `for<'a> fn(&'a str) {f}`
- = help: consider constraining the associated type `<i32 as With>::F` to `for<'a> fn(&'a str) {f}` or calling a method that returns `<i32 as With>::F`
- = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
-note: tuple struct defined here
- --> $DIR/lazy-nested-obligations-2.rs:16:16
- |
-LL | pub struct V<T: With>(<T as With>::F);
- | ^
-
-error[E0308]: mismatched types
- --> $DIR/lazy-nested-obligations-2.rs:21:30
- |
-LL | let _: E3<i32> = E3::Var(f);
- | ------- ^ types differ
- | |
- | arguments to this enum variant are incorrect
- |
- = note: expected associated type `<i32 as With>::F`
- found fn item `for<'a> fn(&'a str) {f}`
- = help: consider constraining the associated type `<i32 as With>::F` to `for<'a> fn(&'a str) {f}` or calling a method that returns `<i32 as With>::F`
- = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
-note: tuple variant defined here
- --> $DIR/lazy-nested-obligations-2.rs:19:9
- |
-LL | Var(<T as With>::F),
- | ^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/new-solver/more-object-bound.stderr b/tests/ui/traits/new-solver/more-object-bound.stderr
index 4554b8c74..54965dee1 100644
--- a/tests/ui/traits/new-solver/more-object-bound.stderr
+++ b/tests/ui/traits/new-solver/more-object-bound.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
- --> $DIR/more-object-bound.rs:12:17
+ --> $DIR/more-object-bound.rs:12:5
|
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
- | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait<A = A, B = B>`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait<A = A, B = B>`
|
note: required by a bound in `foo`
--> $DIR/more-object-bound.rs:18:8
diff --git a/tests/ui/traits/new-solver/normalize-unsize-rhs.rs b/tests/ui/traits/new-solver/normalize-unsize-rhs.rs
new file mode 100644
index 000000000..a398ab4f2
--- /dev/null
+++ b/tests/ui/traits/new-solver/normalize-unsize-rhs.rs
@@ -0,0 +1,23 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+#![feature(trait_upcasting)]
+
+trait A {}
+trait B: A {}
+
+impl A for usize {}
+impl B for usize {}
+
+trait Mirror {
+ type Assoc: ?Sized;
+}
+
+impl<T: ?Sized> Mirror for T {
+ type Assoc = T;
+}
+
+fn main() {
+ let x = Box::new(1usize) as Box<<dyn B as Mirror>::Assoc>;
+ let y = x as Box<<dyn A as Mirror>::Assoc>;
+}
diff --git a/tests/ui/traits/new-solver/object-soundness-requires-generalization.rs b/tests/ui/traits/new-solver/object-soundness-requires-generalization.rs
new file mode 100644
index 000000000..d02dada72
--- /dev/null
+++ b/tests/ui/traits/new-solver/object-soundness-requires-generalization.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Ztrait-solver=next
+// ignore-test
+
+trait Trait {
+ type Gat<'lt>;
+}
+impl Trait for u8 {
+ type Gat<'lt> = u8;
+}
+
+fn test<T: Trait, F: FnOnce(<T as Trait>::Gat<'_>) -> S + ?Sized, S>() {}
+
+fn main() {
+ // Proving `dyn FnOnce: FnOnce` requires making sure that all of the supertraits
+ // of the trait and associated type bounds hold. We check this in
+ // `predicates_for_object_candidate`, and eagerly replace projections using equality
+ // which may generalize a type and emit a nested AliasRelate goal. Make sure that
+ // we don't ICE in that case, and bubble that goal up to the caller.
+ test::<u8, dyn FnOnce(<u8 as Trait>::Gat<'_>) + 'static, _>();
+}
diff --git a/tests/ui/traits/new-solver/exponential-trait-goals.rs b/tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs
index b37f09ee1..b37f09ee1 100644
--- a/tests/ui/traits/new-solver/exponential-trait-goals.rs
+++ b/tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs
diff --git a/tests/ui/traits/new-solver/exponential-trait-goals.stderr b/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr
index 28a99cbbc..28a99cbbc 100644
--- a/tests/ui/traits/new-solver/exponential-trait-goals.stderr
+++ b/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr
diff --git a/tests/ui/traits/new-solver/overflow/global-cache.rs b/tests/ui/traits/new-solver/overflow/global-cache.rs
new file mode 100644
index 000000000..adc03da04
--- /dev/null
+++ b/tests/ui/traits/new-solver/overflow/global-cache.rs
@@ -0,0 +1,23 @@
+// compile-flags: -Ztrait-solver=next
+
+// Check that we consider the reached depth of global cache
+// entries when detecting overflow. We would otherwise be unstable
+// wrt to incremental compilation.
+#![recursion_limit = "9"]
+
+trait Trait {}
+
+struct Inc<T>(T);
+
+impl<T: Trait> Trait for Inc<T> {}
+impl Trait for () {}
+
+fn impls_trait<T: Trait>() {}
+
+type Four<T> = Inc<Inc<Inc<Inc<T>>>>;
+
+fn main() {
+ impls_trait::<Four<Four<()>>>();
+ impls_trait::<Four<Four<Four<Four<()>>>>>();
+ //~^ ERROR overflow evaluating the requirement
+}
diff --git a/tests/ui/traits/new-solver/overflow/global-cache.stderr b/tests/ui/traits/new-solver/overflow/global-cache.stderr
new file mode 100644
index 000000000..f3b86a083
--- /dev/null
+++ b/tests/ui/traits/new-solver/overflow/global-cache.stderr
@@ -0,0 +1,16 @@
+error[E0275]: overflow evaluating the requirement `Inc<Inc<Inc<Inc<Inc<Inc<Inc<...>>>>>>>: Trait`
+ --> $DIR/global-cache.rs:21:5
+ |
+LL | impls_trait::<Four<Four<Four<Four<()>>>>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "18"]` attribute to your crate (`global_cache`)
+note: required by a bound in `impls_trait`
+ --> $DIR/global-cache.rs:15:19
+ |
+LL | fn impls_trait<T: Trait>() {}
+ | ^^^^^ required by this bound in `impls_trait`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/new-solver/recursive-self-normalization-2.rs b/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs
index d086db475..d086db475 100644
--- a/tests/ui/traits/new-solver/recursive-self-normalization-2.rs
+++ b/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs
diff --git a/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr b/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr
index eebaf21d7..eebaf21d7 100644
--- a/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr
+++ b/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr
diff --git a/tests/ui/traits/new-solver/recursive-self-normalization.rs b/tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs
index d15df7dea..d15df7dea 100644
--- a/tests/ui/traits/new-solver/recursive-self-normalization.rs
+++ b/tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs
diff --git a/tests/ui/traits/new-solver/recursive-self-normalization.stderr b/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr
index 6a87fe2f1..6a87fe2f1 100644
--- a/tests/ui/traits/new-solver/recursive-self-normalization.stderr
+++ b/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr
diff --git a/tests/ui/traits/new-solver/trait-upcast-lhs-needs-normalization.rs b/tests/ui/traits/new-solver/trait-upcast-lhs-needs-normalization.rs
new file mode 100644
index 000000000..43cd773bf
--- /dev/null
+++ b/tests/ui/traits/new-solver/trait-upcast-lhs-needs-normalization.rs
@@ -0,0 +1,20 @@
+// check-pass
+// compile-flags: -Ztrait-solver=next
+
+#![feature(trait_upcasting)]
+
+pub trait A {}
+pub trait B: A {}
+
+pub trait Mirror {
+ type Assoc: ?Sized;
+}
+impl<T: ?Sized> Mirror for T {
+ type Assoc = T;
+}
+
+pub fn foo<'a>(x: &'a <dyn B + 'static as Mirror>::Assoc) -> &'a (dyn A + 'static) {
+ x
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/unsize-although-ambiguous.rs b/tests/ui/traits/new-solver/unsize-although-ambiguous.rs
new file mode 100644
index 000000000..431988a5f
--- /dev/null
+++ b/tests/ui/traits/new-solver/unsize-although-ambiguous.rs
@@ -0,0 +1,13 @@
+// check-pass
+// compile-flags: -Ztrait-solver=next
+
+use std::fmt::Display;
+
+fn box_dyn_display(_: Box<dyn Display>) {}
+
+fn main() {
+ // During coercion, we don't necessarily know whether `{integer}` implements
+ // `Display`. Before, that would cause us to bail out in the coercion loop when
+ // checking `{integer}: Unsize<dyn Display>`.
+ box_dyn_display(Box::new(1));
+}
diff --git a/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.rs b/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.rs
new file mode 100644
index 000000000..ba55ab071
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+#![feature(non_lifetime_binders)]
+//~^ WARN is incomplete and may not be safe
+
+pub fn foo()
+where
+ for<V> V: Sized,
+{
+ bar();
+}
+
+pub fn bar()
+where
+ for<V> V: Sized,
+{
+}
+
+pub fn main() {}
diff --git a/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.stderr b/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.stderr
new file mode 100644
index 000000000..e75d81270
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.stderr
@@ -0,0 +1,11 @@
+warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/sized-late-bound-issue-114872.rs:3:12
+ |
+LL | #![feature(non_lifetime_binders)]
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/object/print_vtable_sizes.rs b/tests/ui/traits/object/print_vtable_sizes.rs
index 565609499..f51060853 100644
--- a/tests/ui/traits/object/print_vtable_sizes.rs
+++ b/tests/ui/traits/object/print_vtable_sizes.rs
@@ -10,8 +10,9 @@ trait C {
fn x() {} // not object safe, shouldn't be reported
}
-// This ideally should not have any upcasting cost,
-// but currently does due to a bug
+// This does not have any upcasting cost,
+// because both `Send` and `Sync` are traits
+// with no methods
trait D: Send + Sync + help::MarkerWithSuper {}
// This can't have no cost without reordering,
diff --git a/tests/ui/traits/object/print_vtable_sizes.stdout b/tests/ui/traits/object/print_vtable_sizes.stdout
index 3ba650bc3..ce90c7621 100644
--- a/tests/ui/traits/object/print_vtable_sizes.stdout
+++ b/tests/ui/traits/object/print_vtable_sizes.stdout
@@ -1,8 +1,8 @@
-print-vtable-sizes { "crate_name": "<UNKNOWN_CRATE>", "trait_name": "D", "entries": "7", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "3", "upcasting_cost_percent": "75" }
print-vtable-sizes { "crate_name": "<UNKNOWN_CRATE>", "trait_name": "E", "entries": "6", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "2", "upcasting_cost_percent": "50" }
print-vtable-sizes { "crate_name": "<UNKNOWN_CRATE>", "trait_name": "G", "entries": "14", "entries_ignoring_upcasting": "11", "entries_for_upcasting": "3", "upcasting_cost_percent": "27.27272727272727" }
print-vtable-sizes { "crate_name": "<UNKNOWN_CRATE>", "trait_name": "A", "entries": "6", "entries_ignoring_upcasting": "5", "entries_for_upcasting": "1", "upcasting_cost_percent": "20" }
print-vtable-sizes { "crate_name": "<UNKNOWN_CRATE>", "trait_name": "B", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
+print-vtable-sizes { "crate_name": "<UNKNOWN_CRATE>", "trait_name": "D", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
print-vtable-sizes { "crate_name": "<UNKNOWN_CRATE>", "trait_name": "F", "entries": "6", "entries_ignoring_upcasting": "6", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
print-vtable-sizes { "crate_name": "<UNKNOWN_CRATE>", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
print-vtable-sizes { "crate_name": "<UNKNOWN_CRATE>", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
index d37943b92..206ab0789 100644
--- a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
+++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
@@ -1,4 +1,3 @@
-//~ ERROR overflow
// A regression test for #111729 checking that we correctly
// track recursion depth for obligations returned by confirmation.
use std::panic::RefUnwindSafe;
@@ -15,6 +14,7 @@ struct RootDatabase {
}
impl<T: RefUnwindSafe> Database for T {
+ //~^ ERROR overflow
type Storage = SalsaStorage;
}
impl Database for RootDatabase {
diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
index 8f9ce3ef1..4123a8199 100644
--- a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
+++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
@@ -1,13 +1,17 @@
error[E0275]: overflow evaluating the requirement `Runtime<RootDatabase>: RefUnwindSafe`
+ --> $DIR/cycle-via-builtin-auto-trait-impl.rs:16:9
+ |
+LL | impl<T: RefUnwindSafe> Database for T {
+ | ^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`cycle_via_builtin_auto_trait_impl`)
note: required because it appears within the type `RootDatabase`
- --> $DIR/cycle-via-builtin-auto-trait-impl.rs:13:8
+ --> $DIR/cycle-via-builtin-auto-trait-impl.rs:12:8
|
LL | struct RootDatabase {
| ^^^^^^^^^^^^
note: required for `RootDatabase` to implement `Database`
- --> $DIR/cycle-via-builtin-auto-trait-impl.rs:17:24
+ --> $DIR/cycle-via-builtin-auto-trait-impl.rs:16:24
|
LL | impl<T: RefUnwindSafe> Database for T {
| ------------- ^^^^^^^^ ^
diff --git a/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr b/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr
index ca98e1831..62c732fb1 100644
--- a/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr
+++ b/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr
@@ -10,6 +10,7 @@ note: cycle used when collecting item types in top-level module
|
LL | trait A: B + A {}
| ^^^^^^^^^^^^^^^^^
+ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: aborting due to previous error
diff --git a/tests/ui/traits/trait-upcasting/fewer-associated.rs b/tests/ui/traits/trait-upcasting/fewer-associated.rs
new file mode 100644
index 000000000..8228eea26
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/fewer-associated.rs
@@ -0,0 +1,25 @@
+// check-pass
+// issue: 114035
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+#![feature(trait_upcasting)]
+
+trait A: B {
+ type Assoc;
+}
+
+trait B {}
+
+fn upcast(a: &dyn A<Assoc = i32>) -> &dyn B {
+ a
+}
+
+// Make sure that we can drop the existential projection `A::Assoc = i32`
+// when upcasting `dyn A<Assoc = i32>` to `dyn B`. Before, we used some
+// complicated algorithm which required rebuilding a new object type with
+// different bounds in order to test that an upcast was valid, but this
+// didn't allow upcasting to t that have fewer associated types
+// than the source type.
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr
new file mode 100644
index 000000000..59c9d5737
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/illegal-upcast-from-impl.rs:16:66
+ |
+LL | fn illegal(x: &dyn Sub<Assoc = ()>) -> &dyn Super<Assoc = i32> { x }
+ | ----------------------- ^ expected trait `Super`, found trait `Sub`
+ | |
+ | expected `&dyn Super<Assoc = i32>` because of return type
+ |
+ = note: expected reference `&dyn Super<Assoc = i32>`
+ found reference `&dyn Sub<Assoc = ()>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr
new file mode 100644
index 000000000..59c9d5737
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/illegal-upcast-from-impl.rs:16:66
+ |
+LL | fn illegal(x: &dyn Sub<Assoc = ()>) -> &dyn Super<Assoc = i32> { x }
+ | ----------------------- ^ expected trait `Super`, found trait `Sub`
+ | |
+ | expected `&dyn Super<Assoc = i32>` because of return type
+ |
+ = note: expected reference `&dyn Super<Assoc = i32>`
+ found reference `&dyn Sub<Assoc = ()>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs
new file mode 100644
index 000000000..774474281
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs
@@ -0,0 +1,23 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+#![feature(trait_upcasting)]
+
+trait Super {
+ type Assoc;
+}
+
+trait Sub: Super {}
+
+impl<T: ?Sized> Super for T {
+ type Assoc = i32;
+}
+
+fn illegal(x: &dyn Sub<Assoc = ()>) -> &dyn Super<Assoc = i32> { x }
+//~^ ERROR mismatched types
+
+// Want to make sure that we can't "upcast" to a supertrait that has a different
+// associated type that is instead provided by a blanket impl (and doesn't come
+// from the object bounds).
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/issue-11515.current.stderr b/tests/ui/traits/trait-upcasting/issue-11515.current.stderr
new file mode 100644
index 000000000..97d66cccb
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/issue-11515.current.stderr
@@ -0,0 +1,13 @@
+error[E0658]: cannot cast `dyn Fn()` to `dyn FnMut()`, trait upcasting coercion is experimental
+ --> $DIR/issue-11515.rs:10:38
+ |
+LL | let test = Box::new(Test { func: closure });
+ | ^^^^^^^
+ |
+ = note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
+ = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
+ = note: required when coercing `Box<(dyn Fn() + 'static)>` into `Box<(dyn FnMut() + 'static)>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/trait-upcasting/issue-11515.next.stderr b/tests/ui/traits/trait-upcasting/issue-11515.next.stderr
new file mode 100644
index 000000000..97d66cccb
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/issue-11515.next.stderr
@@ -0,0 +1,13 @@
+error[E0658]: cannot cast `dyn Fn()` to `dyn FnMut()`, trait upcasting coercion is experimental
+ --> $DIR/issue-11515.rs:10:38
+ |
+LL | let test = Box::new(Test { func: closure });
+ | ^^^^^^^
+ |
+ = note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
+ = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
+ = note: required when coercing `Box<(dyn Fn() + 'static)>` into `Box<(dyn FnMut() + 'static)>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/trait-upcasting/issue-11515.rs b/tests/ui/traits/trait-upcasting/issue-11515.rs
new file mode 100644
index 000000000..723f3a24f
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/issue-11515.rs
@@ -0,0 +1,11 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+struct Test {
+ func: Box<dyn FnMut() + 'static>,
+}
+
+fn main() {
+ let closure: Box<dyn Fn() + 'static> = Box::new(|| ());
+ let test = Box::new(Test { func: closure }); //~ ERROR trait upcasting coercion is experimental [E0658]
+}
diff --git a/tests/ui/traits/trait-upcasting/normalization.rs b/tests/ui/traits/trait-upcasting/normalization.rs
new file mode 100644
index 000000000..c78338b0d
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/normalization.rs
@@ -0,0 +1,20 @@
+// check-pass
+// issue: 114113
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+#![feature(trait_upcasting)]
+
+trait Mirror {
+ type Assoc;
+}
+impl<T> Mirror for T {
+ type Assoc = T;
+}
+
+trait Bar<T> {}
+trait Foo<T>: Bar<<T as Mirror>::Assoc> {}
+
+fn upcast<T>(x: &dyn Foo<T>) -> &dyn Bar<T> { x }
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr
new file mode 100644
index 000000000..b612005fc
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr
@@ -0,0 +1,9 @@
+error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
+ --> $DIR/type-checking-test-1.rs:19:13
+ |
+LL | let _ = x as &dyn Bar<_>; // Ambiguous
+ | ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr
new file mode 100644
index 000000000..b612005fc
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr
@@ -0,0 +1,9 @@
+error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
+ --> $DIR/type-checking-test-1.rs:19:13
+ |
+LL | let _ = x as &dyn Bar<_>; // Ambiguous
+ | ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
index 6bc9f4a75..afea8521e 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
@@ -1,3 +1,6 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
#![feature(trait_upcasting)]
trait Foo: Bar<i32> + Bar<u32> {}
@@ -15,7 +18,6 @@ fn test_specific(x: &dyn Foo) {
fn test_unknown_version(x: &dyn Foo) {
let _ = x as &dyn Bar<_>; // Ambiguous
//~^ ERROR non-primitive cast
- //~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied
}
fn test_infer_version(x: &dyn Foo) {
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr
deleted file mode 100644
index 82b4e9bd7..000000000
--- a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
- --> $DIR/type-checking-test-1.rs:16:13
- |
-LL | let _ = x as &dyn Bar<_>; // Ambiguous
- | ^^^^^^^^^^^^^^^^ invalid cast
- |
-help: consider borrowing the value
- |
-LL | let _ = &x as &dyn Bar<_>; // Ambiguous
- | +
-
-error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
- --> $DIR/type-checking-test-1.rs:16:13
- |
-LL | let _ = x as &dyn Bar<_>; // Ambiguous
- | ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
- |
- = note: required for the cast from `&&dyn Foo` to `&dyn Bar<_>`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0277, E0605.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-2.rs b/tests/ui/traits/trait-upcasting/type-checking-test-2.rs
index 36b11dffd..b024b2775 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-2.rs
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-2.rs
@@ -18,13 +18,11 @@ fn test_specific2(x: &dyn Foo<u32>) {
fn test_specific3(x: &dyn Foo<i32>) {
let _ = x as &dyn Bar<u32>; // Error
//~^ ERROR non-primitive cast
- //~^^ ERROR the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
}
fn test_infer_arg(x: &dyn Foo<u32>) {
let a = x as &dyn Bar<_>; // Ambiguous
//~^ ERROR non-primitive cast
- //~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
let _ = a.bar();
}
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr
index 856303ef4..3e59b9d33 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr
@@ -2,41 +2,14 @@ error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>`
--> $DIR/type-checking-test-2.rs:19:13
|
LL | let _ = x as &dyn Bar<u32>; // Error
- | ^^^^^^^^^^^^^^^^^^ invalid cast
- |
-help: consider borrowing the value
- |
-LL | let _ = &x as &dyn Bar<u32>; // Error
- | +
-
-error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
- --> $DIR/type-checking-test-2.rs:19:13
- |
-LL | let _ = x as &dyn Bar<u32>; // Error
- | ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>`
- |
- = note: required for the cast from `&&dyn Foo<i32>` to `&dyn Bar<u32>`
+ | ^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
- --> $DIR/type-checking-test-2.rs:25:13
+ --> $DIR/type-checking-test-2.rs:24:13
|
LL | let a = x as &dyn Bar<_>; // Ambiguous
- | ^^^^^^^^^^^^^^^^ invalid cast
- |
-help: consider borrowing the value
- |
-LL | let a = &x as &dyn Bar<_>; // Ambiguous
- | +
-
-error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
- --> $DIR/type-checking-test-2.rs:25:13
- |
-LL | let a = x as &dyn Bar<_>; // Ambiguous
- | ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>`
- |
- = note: required for the cast from `&&dyn Foo<u32>` to `&dyn Bar<_>`
+ | ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0277, E0605.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr
new file mode 100644
index 000000000..9f0993d65
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr
@@ -0,0 +1,13 @@
+error[E0658]: cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
+ --> $DIR/upcast-through-struct-tail.rs:10:5
+ |
+LL | x
+ | ^
+ |
+ = note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
+ = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
+ = note: required when coercing `Box<Wrapper<(dyn A + 'a)>>` into `Box<Wrapper<(dyn B + 'a)>>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr
new file mode 100644
index 000000000..9f0993d65
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr
@@ -0,0 +1,13 @@
+error[E0658]: cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
+ --> $DIR/upcast-through-struct-tail.rs:10:5
+ |
+LL | x
+ | ^
+ |
+ = note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
+ = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
+ = note: required when coercing `Box<Wrapper<(dyn A + 'a)>>` into `Box<Wrapper<(dyn B + 'a)>>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs
new file mode 100644
index 000000000..42495f45f
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs
@@ -0,0 +1,14 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+struct Wrapper<T: ?Sized>(T);
+
+trait A: B {}
+trait B {}
+
+fn test<'a>(x: Box<Wrapper<dyn A + 'a>>) -> Box<Wrapper<dyn B + 'a>> {
+ x
+ //~^ ERROR cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
+}
+
+fn main() {}
diff --git a/tests/ui/traits/vtable/multiple-markers.rs b/tests/ui/traits/vtable/multiple-markers.rs
new file mode 100644
index 000000000..1e6e30870
--- /dev/null
+++ b/tests/ui/traits/vtable/multiple-markers.rs
@@ -0,0 +1,47 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/113840>
+//
+// This test makes sure that multiple marker (method-less) traits can reuse the
+// same pointer for upcasting.
+//
+// build-fail
+#![crate_type = "lib"]
+#![feature(rustc_attrs)]
+
+// Markers
+trait M0 {}
+trait M1 {}
+trait M2 {}
+
+// Just a trait with a method
+trait T {
+ fn method(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait A: M0 + M1 + M2 + T {} //~ error: vtable entries for `<S as A>`:
+
+#[rustc_dump_vtable]
+trait B: M0 + M1 + T + M2 {} //~ error: vtable entries for `<S as B>`:
+
+#[rustc_dump_vtable]
+trait C: M0 + T + M1 + M2 {} //~ error: vtable entries for `<S as C>`:
+
+#[rustc_dump_vtable]
+trait D: T + M0 + M1 + M2 {} //~ error: vtable entries for `<S as D>`:
+
+struct S;
+
+impl M0 for S {}
+impl M1 for S {}
+impl M2 for S {}
+impl T for S {}
+impl A for S {}
+impl B for S {}
+impl C for S {}
+impl D for S {}
+
+pub fn require_vtables() {
+ fn require_vtables(_: &dyn A, _: &dyn B, _: &dyn C, _: &dyn D) {}
+
+ require_vtables(&S, &S, &S, &S)
+}
diff --git a/tests/ui/traits/vtable/multiple-markers.stderr b/tests/ui/traits/vtable/multiple-markers.stderr
new file mode 100644
index 000000000..4497c703a
--- /dev/null
+++ b/tests/ui/traits/vtable/multiple-markers.stderr
@@ -0,0 +1,52 @@
+error: vtable entries for `<S as A>`: [
+ MetadataDropInPlace,
+ MetadataSize,
+ MetadataAlign,
+ Method(<S as T>::method),
+ ]
+ --> $DIR/multiple-markers.rs:21:1
+ |
+LL | trait A: M0 + M1 + M2 + T {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: vtable entries for `<S as B>`: [
+ MetadataDropInPlace,
+ MetadataSize,
+ MetadataAlign,
+ Method(<S as T>::method),
+ TraitVPtr(<S as M2>),
+ ]
+ --> $DIR/multiple-markers.rs:24:1
+ |
+LL | trait B: M0 + M1 + T + M2 {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: vtable entries for `<S as C>`: [
+ MetadataDropInPlace,
+ MetadataSize,
+ MetadataAlign,
+ Method(<S as T>::method),
+ TraitVPtr(<S as M1>),
+ TraitVPtr(<S as M2>),
+ ]
+ --> $DIR/multiple-markers.rs:27:1
+ |
+LL | trait C: M0 + T + M1 + M2 {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: vtable entries for `<S as D>`: [
+ MetadataDropInPlace,
+ MetadataSize,
+ MetadataAlign,
+ Method(<S as T>::method),
+ TraitVPtr(<S as M0>),
+ TraitVPtr(<S as M1>),
+ TraitVPtr(<S as M2>),
+ ]
+ --> $DIR/multiple-markers.rs:30:1
+ |
+LL | trait D: T + M0 + M1 + M2 {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+