about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-04-15 11:20:33 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-06-13 10:41:52 +0000
commitc75f7283bf52c6e2ec6a178f2b7717a4daddacf4 (patch)
tree05d2c77ddb1ba67d34880c15d0a271b7af1cb9dc
parentb28221e74f5f05d0f7a6212f99c9d5af868c0ed3 (diff)
downloadrust-c75f7283bf52c6e2ec6a178f2b7717a4daddacf4.tar.gz
rust-c75f7283bf52c6e2ec6a178f2b7717a4daddacf4.zip
Add some tests
-rw-r--r--tests/ui/impl-trait/call_method_ambiguous.next.stderr17
-rw-r--r--tests/ui/impl-trait/call_method_ambiguous.rs39
-rw-r--r--tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr17
-rw-r--r--tests/ui/impl-trait/call_method_on_inherent_impl.rs25
-rw-r--r--tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr16
-rw-r--r--tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr17
-rw-r--r--tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs22
-rw-r--r--tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr40
-rw-r--r--tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr31
-rw-r--r--tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs35
-rw-r--r--tests/ui/impl-trait/call_method_without_import.no_import.stderr37
-rw-r--r--tests/ui/impl-trait/call_method_without_import.rs42
-rw-r--r--tests/ui/impl-trait/method-resolution.current.stderr36
-rw-r--r--tests/ui/impl-trait/method-resolution.rs29
-rw-r--r--tests/ui/impl-trait/method-resolution2.next.stderr20
-rw-r--r--tests/ui/impl-trait/method-resolution2.rs31
-rw-r--r--tests/ui/impl-trait/method-resolution3.current.stderr37
-rw-r--r--tests/ui/impl-trait/method-resolution3.next.stderr20
-rw-r--r--tests/ui/impl-trait/method-resolution3.rs29
-rw-r--r--tests/ui/impl-trait/method-resolution4.next.stderr22
-rw-r--r--tests/ui/impl-trait/method-resolution4.rs20
-rw-r--r--tests/ui/impl-trait/recursive-parent-trait-method-call.rs42
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution.current.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution.next.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution.rs30
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution2.current.stderr36
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution2.rs30
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution3.current.stderr21
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution3.next.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution3.rs36
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution4.current.stderr21
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution4.next.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution4.rs39
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution5.current.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution5.rs34
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs31
38 files changed, 998 insertions, 0 deletions
diff --git a/tests/ui/impl-trait/call_method_ambiguous.next.stderr b/tests/ui/impl-trait/call_method_ambiguous.next.stderr
new file mode 100644
index 00000000000..cd222aa7ae9
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_ambiguous.next.stderr
@@ -0,0 +1,17 @@
+error[E0282]: type annotations needed
+  --> $DIR/call_method_ambiguous.rs:29:13
+   |
+LL |         let mut iter = foo(n - 1, m);
+   |             ^^^^^^^^
+LL |
+LL |         assert_eq!(iter.get(), 1);
+   |                    ---- type must be known at this point
+   |
+help: consider giving `iter` an explicit type
+   |
+LL |         let mut iter: /* Type */ = foo(n - 1, m);
+   |                     ++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/call_method_ambiguous.rs b/tests/ui/impl-trait/call_method_ambiguous.rs
new file mode 100644
index 00000000000..c26c01e002d
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_ambiguous.rs
@@ -0,0 +1,39 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@[current] run-pass
+
+#![feature(precise_capturing)]
+#![allow(incomplete_features)]
+
+trait Get {
+    fn get(&mut self) -> u32;
+}
+
+impl Get for () {
+    fn get(&mut self) -> u32 {
+        0
+    }
+}
+
+impl<T> Get for &mut T
+where
+    T: Get,
+{
+    fn get(&mut self) -> u32 {
+        T::get(self) + 1
+    }
+}
+
+fn foo(n: usize, m: &mut ()) -> impl use<'_> Get {
+    if n > 0 {
+        let mut iter = foo(n - 1, m);
+        //[next]~^ type annotations needed
+        assert_eq!(iter.get(), 1);
+    }
+    m
+}
+
+fn main() {
+    let g = foo(1, &mut ()).get();
+    assert_eq!(g, 1);
+}
diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr
new file mode 100644
index 00000000000..271051f120a
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr
@@ -0,0 +1,17 @@
+error[E0282]: type annotations needed
+  --> $DIR/call_method_on_inherent_impl.rs:18:13
+   |
+LL |         let x = my_foo();
+   |             ^
+LL |
+LL |         x.my_debug();
+   |         - type must be known at this point
+   |
+help: consider giving `x` an explicit type
+   |
+LL |         let x: /* Type */ = my_foo();
+   |              ++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl.rs b/tests/ui/impl-trait/call_method_on_inherent_impl.rs
new file mode 100644
index 00000000000..17f7cad660d
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_on_inherent_impl.rs
@@ -0,0 +1,25 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@[current] check-pass
+
+trait MyDebug {
+    fn my_debug(&self);
+}
+
+impl<T> MyDebug for T
+where
+    T: std::fmt::Debug,
+{
+    fn my_debug(&self) {}
+}
+
+fn my_foo() -> impl std::fmt::Debug {
+    if false {
+        let x = my_foo();
+        //[next]~^ type annotations needed
+        x.my_debug();
+    }
+    ()
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr
new file mode 100644
index 00000000000..6ecb2b05fc5
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr
@@ -0,0 +1,16 @@
+error[E0599]: no method named `my_debug` found for reference `&impl Debug` in the current scope
+  --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:16:11
+   |
+LL |         x.my_debug();
+   |           ^^^^^^^^ method not found in `&impl Debug`
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it
+  --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:4:1
+   |
+LL | trait MyDebug {
+   | ^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr
new file mode 100644
index 00000000000..5fb0b8f1d14
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr
@@ -0,0 +1,17 @@
+error[E0282]: type annotations needed for `&_`
+  --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:14:13
+   |
+LL |         let x = &my_foo();
+   |             ^
+LL |
+LL |         x.my_debug();
+   |           -------- type must be known at this point
+   |
+help: consider giving `x` an explicit type, where the placeholders `_` are specified
+   |
+LL |         let x: &_ = &my_foo();
+   |              ++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs
new file mode 100644
index 00000000000..7fb2ff3b2bc
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs
@@ -0,0 +1,22 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+
+trait MyDebug {
+    fn my_debug(&self);
+}
+
+impl MyDebug for &() {
+    fn my_debug(&self) {}
+}
+
+fn my_foo() -> impl std::fmt::Debug {
+    if false {
+        let x = &my_foo();
+        //[next]~^ ERROR: type annotations needed
+        x.my_debug();
+        //[current]~^ ERROR: no method named `my_debug`
+    }
+    ()
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr
new file mode 100644
index 00000000000..fe6e166cb4f
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr
@@ -0,0 +1,40 @@
+error[E0599]: no method named `my_debug` found for opaque type `impl Debug` in the current scope
+  --> $DIR/call_method_on_inherent_impl_ref.rs:20:11
+   |
+LL |     fn my_debug(&self);
+   |        -------- the method is available for `&impl Debug` here
+...
+LL |         x.my_debug();
+   |           ^^^^^^^^ method not found in `impl Debug`
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it
+  --> $DIR/call_method_on_inherent_impl_ref.rs:4:1
+   |
+LL | trait MyDebug {
+   | ^^^^^^^^^^^^^
+
+error[E0391]: cycle detected when computing type of opaque `my_foo::{opaque#0}`
+  --> $DIR/call_method_on_inherent_impl_ref.rs:15:16
+   |
+LL | fn my_foo() -> impl std::fmt::Debug {
+   |                ^^^^^^^^^^^^^^^^^^^^
+   |
+note: ...which requires type-checking `my_foo`...
+  --> $DIR/call_method_on_inherent_impl_ref.rs:20:9
+   |
+LL |         x.my_debug();
+   |         ^
+   = note: ...which requires evaluating trait selection obligation `my_foo::{opaque#0}: core::marker::Unpin`...
+   = note: ...which again requires computing type of opaque `my_foo::{opaque#0}`, completing the cycle
+note: cycle used when computing type of `my_foo::{opaque#0}`
+  --> $DIR/call_method_on_inherent_impl_ref.rs:15:16
+   |
+LL | fn my_foo() -> impl std::fmt::Debug {
+   |                ^^^^^^^^^^^^^^^^^^^^
+   = 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 2 previous errors
+
+Some errors have detailed explanations: E0391, E0599.
+For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr
new file mode 100644
index 00000000000..327f6ca3450
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr
@@ -0,0 +1,31 @@
+error[E0282]: type annotations needed
+  --> $DIR/call_method_on_inherent_impl_ref.rs:18:13
+   |
+LL |         let x = my_foo();
+   |             ^
+LL |
+LL |         x.my_debug();
+   |         - type must be known at this point
+   |
+help: consider giving `x` an explicit type
+   |
+LL |         let x: /* Type */ = my_foo();
+   |              ++++++++++++
+
+error[E0282]: type annotations needed for `&_`
+  --> $DIR/call_method_on_inherent_impl_ref.rs:28:13
+   |
+LL |         let x = &my_bar();
+   |             ^
+LL |
+LL |         x.my_debug();
+   |           -------- type must be known at this point
+   |
+help: consider giving `x` an explicit type, where the placeholders `_` are specified
+   |
+LL |         let x: &_ = &my_bar();
+   |              ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs
new file mode 100644
index 00000000000..40ad21532a4
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs
@@ -0,0 +1,35 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+
+trait MyDebug {
+    fn my_debug(&self);
+}
+
+impl<T> MyDebug for &T
+where
+    T: std::fmt::Debug,
+{
+    fn my_debug(&self) {}
+}
+
+fn my_foo() -> impl std::fmt::Debug {
+    //[current]~^ cycle
+    if false {
+        let x = my_foo();
+        //[next]~^ type annotations needed
+        x.my_debug();
+        //[current]~^ no method named `my_debug` found
+    }
+    ()
+}
+
+fn my_bar() -> impl std::fmt::Debug {
+    if false {
+        let x = &my_bar();
+        //[next]~^ type annotations needed
+        x.my_debug();
+    }
+    ()
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/call_method_without_import.no_import.stderr b/tests/ui/impl-trait/call_method_without_import.no_import.stderr
new file mode 100644
index 00000000000..72982b695bb
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_without_import.no_import.stderr
@@ -0,0 +1,37 @@
+error[E0599]: no method named `fmt` found for opaque type `impl Debug` in the current scope
+  --> $DIR/call_method_without_import.rs:17:11
+   |
+LL |         x.fmt(f);
+   |           ^^^ method not found in `impl Debug`
+  --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
+   |
+   = note: the method is available for `impl Debug` here
+   |
+   = help: items from traits can only be used if the trait is in scope
+help: trait `Debug` which provides `fmt` is implemented but not in scope; perhaps you want to import it
+   |
+LL + use std::fmt::Debug;
+   |
+
+error[E0599]: no method named `fmt` found for mutable reference `&mut impl Debug` in the current scope
+  --> $DIR/call_method_without_import.rs:26:11
+   |
+LL |         x.fmt(f);
+   |           ^^^ method not found in `&mut impl Debug`
+   |
+   = help: items from traits can only be used if the trait is in scope
+help: the following traits which provide `fmt` are implemented but not in scope; perhaps you want to import one of them
+   |
+LL + use std::fmt::Binary;
+   |
+LL + use std::fmt::Debug;
+   |
+LL + use std::fmt::Display;
+   |
+LL + use std::fmt::LowerExp;
+   |
+     and 5 other candidates
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/impl-trait/call_method_without_import.rs b/tests/ui/impl-trait/call_method_without_import.rs
new file mode 100644
index 00000000000..d62777ea283
--- /dev/null
+++ b/tests/ui/impl-trait/call_method_without_import.rs
@@ -0,0 +1,42 @@
+//! Test that opaque types only pick up methods from traits in their bounds
+//! if the trait is imported.
+//!
+//! FIXME: always look through the bounds of an opaque type to see if there are
+//! methods that could be called on any of the bound traits, irrespective of
+//! imported traits.
+
+//@ revisions: import no_import
+//@[import] check-pass
+
+#[cfg(import)]
+use std::fmt::Debug as _;
+
+fn foo(f: &mut std::fmt::Formatter<'_>) -> impl std::fmt::Debug {
+    if false {
+        let x = foo(f);
+        x.fmt(f);
+        //[no_import]~^ ERROR: no method named `fmt` found
+    }
+    ()
+}
+
+fn foo1(f: &mut std::fmt::Formatter<'_>) -> impl std::fmt::Debug {
+    if false {
+        let x = &mut foo(f);
+        x.fmt(f);
+        //[no_import]~^ ERROR: no method named `fmt` found
+    }
+    ()
+}
+
+// inconsistent with this
+fn bar<T>(t: impl std::fmt::Debug, f: &mut std::fmt::Formatter<'_>) {
+    t.fmt(f);
+}
+
+// and the desugared version, of course
+fn baz<T: std::fmt::Debug>(t: T, f: &mut std::fmt::Formatter<'_>) {
+    t.fmt(f);
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/method-resolution.current.stderr b/tests/ui/impl-trait/method-resolution.current.stderr
new file mode 100644
index 00000000000..6d10693c893
--- /dev/null
+++ b/tests/ui/impl-trait/method-resolution.current.stderr
@@ -0,0 +1,36 @@
+error[E0599]: no method named `bar` found for struct `Bar<impl Sized>` in the current scope
+  --> $DIR/method-resolution.rs:23:11
+   |
+LL | struct Bar<T>(T);
+   | ------------- method `bar` not found for this struct
+...
+LL |         x.bar();
+   |           ^^^ method not found in `Bar<impl Sized>`
+   |
+   = note: the method was found for
+           - `Bar<u32>`
+
+error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}`
+  --> $DIR/method-resolution.rs:19:24
+   |
+LL | fn foo(x: bool) -> Bar<impl Sized> {
+   |                        ^^^^^^^^^^
+   |
+note: ...which requires type-checking `foo`...
+  --> $DIR/method-resolution.rs:23:9
+   |
+LL |         x.bar();
+   |         ^
+   = note: ...which requires evaluating trait selection obligation `Bar<foo::{opaque#0}>: core::marker::Unpin`...
+   = note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle
+note: cycle used when computing type of `foo::{opaque#0}`
+  --> $DIR/method-resolution.rs:19:24
+   |
+LL | fn foo(x: bool) -> Bar<impl Sized> {
+   |                        ^^^^^^^^^^
+   = 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 2 previous errors
+
+Some errors have detailed explanations: E0391, E0599.
+For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/impl-trait/method-resolution.rs b/tests/ui/impl-trait/method-resolution.rs
new file mode 100644
index 00000000000..07618aa6408
--- /dev/null
+++ b/tests/ui/impl-trait/method-resolution.rs
@@ -0,0 +1,29 @@
+//! Check that we do not constrain hidden types during method resolution.
+//! Otherwise we'd pick up that calling `bar` can be satisfied iff `u32`
+//! is the hidden type of the RPIT.
+
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@[next] check-pass
+
+trait Trait {}
+
+impl Trait for u32 {}
+
+struct Bar<T>(T);
+
+impl Bar<u32> {
+    fn bar(self) {}
+}
+
+fn foo(x: bool) -> Bar<impl Sized> {
+    //[current]~^ ERROR: cycle detected
+    if x {
+        let x = foo(false);
+        x.bar();
+        //[current]~^ ERROR: no method named `bar` found
+    }
+    todo!()
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/method-resolution2.next.stderr b/tests/ui/impl-trait/method-resolution2.next.stderr
new file mode 100644
index 00000000000..223430e1658
--- /dev/null
+++ b/tests/ui/impl-trait/method-resolution2.next.stderr
@@ -0,0 +1,20 @@
+error[E0034]: multiple applicable items in scope
+  --> $DIR/method-resolution2.rs:25:11
+   |
+LL |         x.bar();
+   |           ^^^ multiple `bar` found
+   |
+note: candidate #1 is defined in an impl for the type `Bar<T>`
+  --> $DIR/method-resolution2.rs:19:5
+   |
+LL |     fn bar(self) {}
+   |     ^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Bar<u32>`
+  --> $DIR/method-resolution2.rs:15:5
+   |
+LL |     fn bar(self) {}
+   |     ^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0034`.
diff --git a/tests/ui/impl-trait/method-resolution2.rs b/tests/ui/impl-trait/method-resolution2.rs
new file mode 100644
index 00000000000..2930b42b8bc
--- /dev/null
+++ b/tests/ui/impl-trait/method-resolution2.rs
@@ -0,0 +1,31 @@
+//! Check that the method call does not constrain the RPIT to `i32`, even though
+//! `i32` is the only trait that satisfies the RPIT's trait bounds.
+
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@[current] check-pass
+
+trait Trait {}
+
+impl Trait for i32 {}
+
+struct Bar<T>(T);
+
+impl Bar<u32> {
+    fn bar(self) {}
+}
+
+impl<T: Trait> Bar<T> {
+    fn bar(self) {}
+}
+
+fn foo(x: bool) -> Bar<impl Trait> {
+    if x {
+        let x = foo(false);
+        x.bar();
+        //[next]~^ ERROR: multiple applicable items in scope
+    }
+    Bar(42_i32)
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/method-resolution3.current.stderr b/tests/ui/impl-trait/method-resolution3.current.stderr
new file mode 100644
index 00000000000..7407b489e32
--- /dev/null
+++ b/tests/ui/impl-trait/method-resolution3.current.stderr
@@ -0,0 +1,37 @@
+error[E0599]: no method named `bar` found for struct `Bar<impl Sized>` in the current scope
+  --> $DIR/method-resolution3.rs:22:11
+   |
+LL | struct Bar<T>(T);
+   | ------------- method `bar` not found for this struct
+...
+LL |         x.bar();
+   |           ^^^ method not found in `Bar<impl Sized>`
+   |
+   = note: the method was found for
+           - `Bar<i32>`
+           - `Bar<u32>`
+
+error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}`
+  --> $DIR/method-resolution3.rs:18:24
+   |
+LL | fn foo(x: bool) -> Bar<impl Sized> {
+   |                        ^^^^^^^^^^
+   |
+note: ...which requires type-checking `foo`...
+  --> $DIR/method-resolution3.rs:22:9
+   |
+LL |         x.bar();
+   |         ^
+   = note: ...which requires evaluating trait selection obligation `Bar<foo::{opaque#0}>: core::marker::Unpin`...
+   = note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle
+note: cycle used when computing type of `foo::{opaque#0}`
+  --> $DIR/method-resolution3.rs:18:24
+   |
+LL | fn foo(x: bool) -> Bar<impl Sized> {
+   |                        ^^^^^^^^^^
+   = 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 2 previous errors
+
+Some errors have detailed explanations: E0391, E0599.
+For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/impl-trait/method-resolution3.next.stderr b/tests/ui/impl-trait/method-resolution3.next.stderr
new file mode 100644
index 00000000000..53b77c620ba
--- /dev/null
+++ b/tests/ui/impl-trait/method-resolution3.next.stderr
@@ -0,0 +1,20 @@
+error[E0034]: multiple applicable items in scope
+  --> $DIR/method-resolution3.rs:22:11
+   |
+LL |         x.bar();
+   |           ^^^ multiple `bar` found
+   |
+note: candidate #1 is defined in an impl for the type `Bar<i32>`
+  --> $DIR/method-resolution3.rs:15:5
+   |
+LL |     fn bar(self) {}
+   |     ^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Bar<u32>`
+  --> $DIR/method-resolution3.rs:11:5
+   |
+LL |     fn bar(self) {}
+   |     ^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0034`.
diff --git a/tests/ui/impl-trait/method-resolution3.rs b/tests/ui/impl-trait/method-resolution3.rs
new file mode 100644
index 00000000000..8474e2da7db
--- /dev/null
+++ b/tests/ui/impl-trait/method-resolution3.rs
@@ -0,0 +1,29 @@
+//! Check that we consider `Bar<impl Sized>` to successfully unify
+//! with both `Bar<u32>` and `Bar<i32>` (in isolation), so we bail
+//! out with ambiguity.
+
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+
+struct Bar<T>(T);
+
+impl Bar<u32> {
+    fn bar(self) {}
+}
+
+impl Bar<i32> {
+    fn bar(self) {}
+}
+
+fn foo(x: bool) -> Bar<impl Sized> {
+    //[current]~^ ERROR: cycle
+    if x {
+        let x = foo(false);
+        x.bar();
+        //[current]~^ ERROR: no method named `bar`
+        //[next]~^^ ERROR: multiple applicable items in scope
+    }
+    todo!()
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr
new file mode 100644
index 00000000000..b48de0af357
--- /dev/null
+++ b/tests/ui/impl-trait/method-resolution4.next.stderr
@@ -0,0 +1,22 @@
+error[E0282]: type annotations needed
+  --> $DIR/method-resolution4.rs:13:9
+   |
+LL |         foo(false).next().unwrap();
+   |         ^^^^^^^^^^ cannot infer type
+
+error[E0308]: mismatched types
+  --> $DIR/method-resolution4.rs:16:5
+   |
+LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
+   |                    ------------------------ the expected opaque type
+...
+LL |     std::iter::empty()
+   |     ^^^^^^^^^^^^^^^^^^ types differ
+   |
+   = note: expected opaque type `impl Iterator<Item = ()>`
+                   found struct `std::iter::Empty<_>`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0282, E0308.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs
new file mode 100644
index 00000000000..3578db7cb55
--- /dev/null
+++ b/tests/ui/impl-trait/method-resolution4.rs
@@ -0,0 +1,20 @@
+//! The recursive method call yields the opaque type. The
+//! `next` method call then constrains the hidden type to `&mut _`
+//! because `next` takes `&mut self`. We never resolve the inference
+//! variable, but get a type mismatch when comparing `&mut _` with
+//! `std::iter::Empty`.
+
+//@[current] check-pass
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+
+fn foo(b: bool) -> impl Iterator<Item = ()> {
+    if b {
+        foo(false).next().unwrap();
+        //[next]~^ type annotations needed
+    }
+    std::iter::empty()
+    //[next]~^ mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/recursive-parent-trait-method-call.rs b/tests/ui/impl-trait/recursive-parent-trait-method-call.rs
new file mode 100644
index 00000000000..4da9a06a465
--- /dev/null
+++ b/tests/ui/impl-trait/recursive-parent-trait-method-call.rs
@@ -0,0 +1,42 @@
+//! This test checks that we can resolve the `boxed` method call to `FutureExt`,
+//! because we know that the anonymous future does not implement `StreamExt`.
+
+//@ edition: 2021
+//@ check-pass
+
+use std::future::Future;
+use std::pin::Pin;
+
+trait FutureExt: Future + Sized + Send + 'static {
+    fn boxed(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'static>> {
+        Box::pin(self)
+    }
+}
+
+trait StreamExt: Future + Sized + Send + 'static {
+    fn boxed(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'static>> {
+        Box::pin(self)
+    }
+}
+
+impl<T: Future + Sized + Send + 'static> FutureExt for T {}
+
+fn go(i: usize) -> impl Future<Output = ()> + Send + 'static {
+    async move {
+        if i != 0 {
+            spawn(async move {
+                let fut = go(i - 1).boxed();
+                fut.await;
+            })
+            .await;
+        }
+    }
+}
+
+pub fn spawn<T: Send>(
+    _: impl Future<Output = T> + Send + 'static,
+) -> impl Future<Output = ()> + Send + 'static {
+    async move { todo!() }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/method_resolution.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution.current.stderr
new file mode 100644
index 00000000000..a9c05ad3342
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution.current.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
+  --> $DIR/method_resolution.rs:21:14
+   |
+LL | struct Bar<T>(T);
+   | ------------- method `bar` not found for this struct
+...
+LL |         self.bar()
+   |              ^^^ method not found in `Bar<u32>`
+   |
+   = note: the method was found for
+           - `Bar<Foo>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution.next.stderr
new file mode 100644
index 00000000000..6b34358a56e
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution.next.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
+  --> $DIR/method_resolution.rs:21:14
+   |
+LL | struct Bar<T>(T);
+   | ------------- method `bar` not found for this struct
+...
+LL |         self.bar()
+   |              ^^^ method cannot be called on `Bar<u32>` due to unsatisfied trait bounds
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution.rs b/tests/ui/type-alias-impl-trait/method_resolution.rs
new file mode 100644
index 00000000000..f636aba15c0
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution.rs
@@ -0,0 +1,30 @@
+//! `Bar<u32>::foo` is not defining `Foo`, so it cannot rely on the fact that
+//! `u32` is the hidden type of `Foo` to call `bar`
+
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Sized;
+
+struct Bar<T>(T);
+
+impl Bar<Foo> {
+    fn bar(mut self) {
+        self.0 = 42_u32;
+    }
+}
+
+impl Bar<u32> {
+    fn foo(self) {
+        self.bar()
+        //~^ ERROR: no method named `bar`
+    }
+}
+
+fn foo() -> Foo {
+    42_u32
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr
new file mode 100644
index 00000000000..e68ea70a8ef
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr
@@ -0,0 +1,36 @@
+error[E0599]: no method named `foo` found for struct `Bar<Foo>` in the current scope
+  --> $DIR/method_resolution2.rs:17:14
+   |
+LL | struct Bar<T>(T);
+   | ------------- method `foo` not found for this struct
+...
+LL |         self.foo()
+   |              ^^^ method not found in `Bar<Foo>`
+   |
+   = note: the method was found for
+           - `Bar<u32>`
+
+error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}`
+  --> $DIR/method_resolution2.rs:10:12
+   |
+LL | type Foo = impl Sized;
+   |            ^^^^^^^^^^
+   |
+note: ...which requires type-checking `<impl at $DIR/method_resolution2.rs:15:1: 15:14>::bar`...
+  --> $DIR/method_resolution2.rs:17:9
+   |
+LL |         self.foo()
+   |         ^^^^
+   = note: ...which requires evaluating trait selection obligation `Bar<Foo>: core::marker::Unpin`...
+   = note: ...which again requires computing type of opaque `Foo::{opaque#0}`, completing the cycle
+note: cycle used when computing type of `Foo::{opaque#0}`
+  --> $DIR/method_resolution2.rs:10:12
+   |
+LL | type Foo = impl Sized;
+   |            ^^^^^^^^^^
+   = 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 2 previous errors
+
+Some errors have detailed explanations: E0391, E0599.
+For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution2.rs b/tests/ui/type-alias-impl-trait/method_resolution2.rs
new file mode 100644
index 00000000000..d252f8640d4
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution2.rs
@@ -0,0 +1,30 @@
+//! Check that we do not unify `Bar<Foo>` with `Bar<u32>`, even though the
+//! `foo` method call can be resolved unambiguously by doing so.
+
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@[next] check-pass
+
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Sized;
+//[current]~^ ERROR: cycle
+
+struct Bar<T>(T);
+
+impl Bar<Foo> {
+    fn bar(self) {
+        self.foo()
+        //[current]~^ ERROR: no method named `foo`
+    }
+}
+
+impl Bar<u32> {
+    fn foo(self) {}
+}
+
+fn foo() -> Foo {
+    42_u32
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr
new file mode 100644
index 00000000000..e992d059daf
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr
@@ -0,0 +1,21 @@
+error[E0307]: invalid `self` parameter type: `Bar<u32>`
+  --> $DIR/method_resolution3.rs:16:18
+   |
+LL |     fn bar(self: Bar<u32>) {
+   |                  ^^^^^^^^
+   |
+   = note: type of `self` must be `Self` or a type that dereferences to it
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0307]: invalid `self` parameter type: `&Bar<u32>`
+  --> $DIR/method_resolution3.rs:21:18
+   |
+LL |     fn baz(self: &Bar<u32>) {
+   |                  ^^^^^^^^^
+   |
+   = note: type of `self` must be `Self` or a type that dereferences to it
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0307`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr
new file mode 100644
index 00000000000..9272017cdf5
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr
@@ -0,0 +1,15 @@
+error[E0271]: type mismatch resolving `Foo == u32`
+  --> $DIR/method_resolution3.rs:16:18
+   |
+LL |     fn bar(self: Bar<u32>) {
+   |                  ^^^^^^^^ types differ
+
+error[E0271]: type mismatch resolving `Foo == u32`
+  --> $DIR/method_resolution3.rs:21:18
+   |
+LL |     fn baz(self: &Bar<u32>) {
+   |                  ^^^^^^^^^ types differ
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.rs b/tests/ui/type-alias-impl-trait/method_resolution3.rs
new file mode 100644
index 00000000000..447f3144b82
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution3.rs
@@ -0,0 +1,36 @@
+//! Check that one cannot use arbitrary self types where a generic parameter
+//! mismatches with an opaque type. In theory this could unify with the opaque
+//! type, registering the generic parameter as the hidden type of the opaque type.
+
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+
+#![feature(type_alias_impl_trait, arbitrary_self_types)]
+
+type Foo = impl Copy;
+
+#[derive(Copy, Clone)]
+struct Bar<T>(T);
+
+impl Bar<Foo> {
+    fn bar(self: Bar<u32>) {
+        //[current]~^ ERROR: invalid `self` parameter
+        //[next]~^^ ERROR: type mismatch resolving `Foo == u32`
+        self.foo()
+    }
+    fn baz(self: &Bar<u32>) {
+        //[current]~^ ERROR: invalid `self` parameter
+        //[next]~^^ ERROR: type mismatch resolving `Foo == u32`
+        self.foo()
+    }
+}
+
+impl Bar<u32> {
+    fn foo(self) {}
+}
+
+fn foo() -> Foo {
+    42_u32
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr
new file mode 100644
index 00000000000..3a2ca18f890
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr
@@ -0,0 +1,21 @@
+error[E0307]: invalid `self` parameter type: `Bar<Foo>`
+  --> $DIR/method_resolution4.rs:27:18
+   |
+LL |     fn foo(self: Bar<Foo>) {
+   |                  ^^^^^^^^
+   |
+   = note: type of `self` must be `Self` or a type that dereferences to it
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0307]: invalid `self` parameter type: `&Bar<Foo>`
+  --> $DIR/method_resolution4.rs:32:20
+   |
+LL |     fn foomp(self: &Bar<Foo>) {
+   |                    ^^^^^^^^^
+   |
+   = note: type of `self` must be `Self` or a type that dereferences to it
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0307`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr
new file mode 100644
index 00000000000..33ed2800ebe
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr
@@ -0,0 +1,15 @@
+error[E0271]: type mismatch resolving `u32 == Foo`
+  --> $DIR/method_resolution4.rs:27:18
+   |
+LL |     fn foo(self: Bar<Foo>) {
+   |                  ^^^^^^^^ types differ
+
+error[E0271]: type mismatch resolving `u32 == Foo`
+  --> $DIR/method_resolution4.rs:32:20
+   |
+LL |     fn foomp(self: &Bar<Foo>) {
+   |                    ^^^^^^^^^ types differ
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.rs b/tests/ui/type-alias-impl-trait/method_resolution4.rs
new file mode 100644
index 00000000000..42ed04b3c30
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution4.rs
@@ -0,0 +1,39 @@
+//! Check that one cannot use arbitrary self types where a generic parameter
+//! mismatches with an opaque type. In theory this could unify with the opaque
+//! type, registering the generic parameter as the hidden type of the opaque type.
+
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+
+#![feature(type_alias_impl_trait, arbitrary_self_types)]
+
+mod foo {
+    pub type Foo = impl Copy;
+
+    fn foo() -> Foo {
+        42_u32
+    }
+}
+use foo::Foo;
+
+#[derive(Copy, Clone)]
+struct Bar<T>(T);
+
+impl Bar<Foo> {
+    fn bar(self) {}
+}
+
+impl Bar<u32> {
+    fn foo(self: Bar<Foo>) {
+        //[current]~^ ERROR: invalid `self` parameter
+        //[next]~^^ ERROR: type mismatch resolving `u32 == Foo`
+        self.bar()
+    }
+    fn foomp(self: &Bar<Foo>) {
+        //[current]~^ ERROR: invalid `self` parameter
+        //[next]~^^ ERROR: type mismatch resolving `u32 == Foo`
+        self.bar()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/method_resolution5.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution5.current.stderr
new file mode 100644
index 00000000000..193e6e14709
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution5.current.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
+  --> $DIR/method_resolution5.rs:25:14
+   |
+LL | struct Bar<T>(T);
+   | ------------- method `bar` not found for this struct
+...
+LL |         self.bar()
+   |              ^^^ method not found in `Bar<u32>`
+   |
+   = note: the method was found for
+           - `Bar<Foo>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution5.rs b/tests/ui/type-alias-impl-trait/method_resolution5.rs
new file mode 100644
index 00000000000..69335c9dede
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution5.rs
@@ -0,0 +1,34 @@
+//! Even though `Bar<u32>::foo` is defining `Foo`, the old solver does
+//! not figure out that `u32` is the hidden type of `Foo` to call `bar`.
+
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@[next] check-pass
+
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Sized;
+
+struct Bar<T>(T);
+
+impl Bar<Foo> {
+    fn bar(mut self) {
+        self.0 = 42_u32;
+    }
+}
+
+impl Bar<u32> {
+    fn foo(self)
+    where
+        Foo:,
+    {
+        self.bar()
+        //[current]~^ ERROR: no method named `bar`
+    }
+}
+
+fn foo() -> Foo {
+    42_u32
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr
new file mode 100644
index 00000000000..f331da1af87
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr
@@ -0,0 +1,15 @@
+error: item does not constrain `Tait::{opaque#0}`, but has it in its signature
+  --> $DIR/method_resolution_trait_method_from_opaque.rs:24:8
+   |
+LL |     fn foo(&mut self) {
+   |        ^^^
+   |
+   = note: consider moving the opaque type's declaration and defining uses into a separate module
+note: this opaque type is in the signature
+  --> $DIR/method_resolution_trait_method_from_opaque.rs:17:13
+   |
+LL | type Tait = impl Iterator<Item = ()>;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
new file mode 100644
index 00000000000..2617ce124c1
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9
+   |
+LL |         self.bar.next().unwrap();
+   |         ^^^^^^^^ cannot infer type
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
new file mode 100644
index 00000000000..b6adf08853f
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
@@ -0,0 +1,31 @@
+//! This test demonstrates how method calls will attempt to unify an opaque type with a reference
+//! if the method takes `&self` as its argument. This is almost never what is desired, as the user
+//! would like to have method resolution happen on the opaque type instead of inferring the hidden
+//! type. Once type-alias-impl-trait requires annotating which functions should constrain the hidden
+//! type, this won't be as much of a problem, as most functions that do method calls on opaque types
+//! won't also be the ones defining the hidden type.
+
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+
+#![feature(type_alias_impl_trait)]
+
+pub struct Foo {
+    bar: Tait,
+}
+
+type Tait = impl Iterator<Item = ()>;
+
+impl Foo {
+    pub fn new() -> Foo {
+        Foo { bar: std::iter::empty() }
+    }
+
+    fn foo(&mut self) {
+        //[current]~^ ERROR: item does not constrain
+        self.bar.next().unwrap();
+        //[next]~^ ERROR: type annotations needed
+    }
+}
+
+fn main() {}