From f30b2eea40ba796bd5291531ca441fb309a75af9 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Apr 2024 11:10:50 +0000 Subject: [PATCH 1/4] Use diagnostic method for diagnostics --- compiler/rustc_hir_typeck/src/callee.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index aa94632b2b077..eefb452145d8d 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -637,7 +637,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; }; - let pick = self.confirm_method( + let pick = self.confirm_method_for_diagnostic( call_expr.span, callee_expr, call_expr, From f5710e8b83ab4c3eba3ea3755fa2e2d845a035a1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Apr 2024 11:20:33 +0000 Subject: [PATCH 2/4] Add some tests --- .../method-resolution.current.stderr | 36 +++++++++++++++++ tests/ui/impl-trait/method-resolution.rs | 29 ++++++++++++++ .../impl-trait/method-resolution2.next.stderr | 20 ++++++++++ tests/ui/impl-trait/method-resolution2.rs | 31 +++++++++++++++ .../method-resolution3.current.stderr | 37 ++++++++++++++++++ .../impl-trait/method-resolution3.next.stderr | 20 ++++++++++ tests/ui/impl-trait/method-resolution3.rs | 29 ++++++++++++++ .../impl-trait/method-resolution4.next.stderr | 22 +++++++++++ tests/ui/impl-trait/method-resolution4.rs | 20 ++++++++++ .../method_resolution.current.stderr | 15 +++++++ .../method_resolution.next.stderr | 19 +++++++++ .../method_resolution.rs | 29 ++++++++++++++ .../method_resolution2.current.stderr | 36 +++++++++++++++++ .../method_resolution2.rs | 30 ++++++++++++++ .../method_resolution3.current.stderr | 21 ++++++++++ .../method_resolution3.next.stderr | 15 +++++++ .../method_resolution3.rs | 36 +++++++++++++++++ .../method_resolution4.current.stderr | 21 ++++++++++ .../method_resolution4.next.stderr | 34 ++++++++++++++++ .../method_resolution4.rs | 39 +++++++++++++++++++ ...ution_trait_method_from_opaque.next.stderr | 9 +++++ ...hod_resolution_trait_method_from_opaque.rs | 31 +++++++++++++++ 22 files changed, 579 insertions(+) create mode 100644 tests/ui/impl-trait/method-resolution.current.stderr create mode 100644 tests/ui/impl-trait/method-resolution.rs create mode 100644 tests/ui/impl-trait/method-resolution2.next.stderr create mode 100644 tests/ui/impl-trait/method-resolution2.rs create mode 100644 tests/ui/impl-trait/method-resolution3.current.stderr create mode 100644 tests/ui/impl-trait/method-resolution3.next.stderr create mode 100644 tests/ui/impl-trait/method-resolution3.rs create mode 100644 tests/ui/impl-trait/method-resolution4.next.stderr create mode 100644 tests/ui/impl-trait/method-resolution4.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution2.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution2.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution3.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution3.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution3.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution4.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution4.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution4.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs 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 0000000000000..6d10693c8933b --- /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` in the current scope + --> $DIR/method-resolution.rs:23:11 + | +LL | struct Bar(T); + | ------------- method `bar` not found for this struct +... +LL | x.bar(); + | ^^^ method not found in `Bar` + | + = note: the method was found for + - `Bar` + +error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}` + --> $DIR/method-resolution.rs:19:24 + | +LL | fn foo(x: bool) -> Bar { + | ^^^^^^^^^^ + | +note: ...which requires type-checking `foo`... + --> $DIR/method-resolution.rs:23:9 + | +LL | x.bar(); + | ^ + = note: ...which requires evaluating trait selection obligation `Bar: 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 { + | ^^^^^^^^^^ + = 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 0000000000000..07618aa64085d --- /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); + +impl Bar { + fn bar(self) {} +} + +fn foo(x: bool) -> Bar { + //[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 0000000000000..223430e1658b4 --- /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` + --> $DIR/method-resolution2.rs:19:5 + | +LL | fn bar(self) {} + | ^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Bar` + --> $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 0000000000000..2930b42b8bca0 --- /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); + +impl Bar { + fn bar(self) {} +} + +impl Bar { + fn bar(self) {} +} + +fn foo(x: bool) -> Bar { + 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 0000000000000..7407b489e324f --- /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` in the current scope + --> $DIR/method-resolution3.rs:22:11 + | +LL | struct Bar(T); + | ------------- method `bar` not found for this struct +... +LL | x.bar(); + | ^^^ method not found in `Bar` + | + = note: the method was found for + - `Bar` + - `Bar` + +error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}` + --> $DIR/method-resolution3.rs:18:24 + | +LL | fn foo(x: bool) -> Bar { + | ^^^^^^^^^^ + | +note: ...which requires type-checking `foo`... + --> $DIR/method-resolution3.rs:22:9 + | +LL | x.bar(); + | ^ + = note: ...which requires evaluating trait selection obligation `Bar: 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 { + | ^^^^^^^^^^ + = 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 0000000000000..53b77c620ba0e --- /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` + --> $DIR/method-resolution3.rs:15:5 + | +LL | fn bar(self) {} + | ^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Bar` + --> $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 0000000000000..8474e2da7dbb9 --- /dev/null +++ b/tests/ui/impl-trait/method-resolution3.rs @@ -0,0 +1,29 @@ +//! Check that we consider `Bar` to successfully unify +//! with both `Bar` and `Bar` (in isolation), so we bail +//! out with ambiguity. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +struct Bar(T); + +impl Bar { + fn bar(self) {} +} + +impl Bar { + fn bar(self) {} +} + +fn foo(x: bool) -> Bar { + //[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 0000000000000..b48de0af3579d --- /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 { + | ------------------------ the expected opaque type +... +LL | std::iter::empty() + | ^^^^^^^^^^^^^^^^^^ types differ + | + = note: expected opaque type `impl Iterator` + 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 0000000000000..3578db7cb55f3 --- /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 { + if b { + foo(false).next().unwrap(); + //[next]~^ type annotations needed + } + std::iter::empty() + //[next]~^ mismatched types +} + +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 0000000000000..bbdcda0604ceb --- /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` in the current scope + --> $DIR/method_resolution.rs:20:14 + | +LL | struct Bar(T); + | ------------- method `bar` not found for this struct +... +LL | self.bar() + | ^^^ method not found in `Bar` + | + = note: the method was found for + - `Bar` + +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 0000000000000..b3c38ea2e1430 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution.next.stderr @@ -0,0 +1,19 @@ +error[E0284]: type annotations needed: cannot satisfy `_ == Foo` + --> $DIR/method_resolution.rs:14:12 + | +LL | fn bar(self) {} + | ^^^^ cannot satisfy `_ == Foo` + +error[E0599]: no method named `bar` found for struct `Bar` in the current scope + --> $DIR/method_resolution.rs:20:14 + | +LL | struct Bar(T); + | ------------- method `bar` not found for this struct +... +LL | self.bar() + | ^^^ method cannot be called on `Bar` due to unsatisfied trait bounds + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0284, E0599. +For more information about an error, try `rustc --explain E0284`. 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 0000000000000..ff4ff91ca7662 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution.rs @@ -0,0 +1,29 @@ +//! check that we do not unify `Bar` with `BAr`, even though the +//! `bar` method call can be resolved unambiguously by doing so. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +#![feature(type_alias_impl_trait)] + +type Foo = impl Sized; + +struct Bar(T); + +impl Bar { + fn bar(self) {} + //[next]~^ ERROR type annotations needed: cannot satisfy `_ == Foo` +} + +impl Bar { + 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 0000000000000..e68ea70a8ef48 --- /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` in the current scope + --> $DIR/method_resolution2.rs:17:14 + | +LL | struct Bar(T); + | ------------- method `foo` not found for this struct +... +LL | self.foo() + | ^^^ method not found in `Bar` + | + = note: the method was found for + - `Bar` + +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 `::bar`... + --> $DIR/method_resolution2.rs:17:9 + | +LL | self.foo() + | ^^^^ + = note: ...which requires evaluating trait selection obligation `Bar: 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 0000000000000..bb747246bf672 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution2.rs @@ -0,0 +1,30 @@ +//! check that we do not unify `Bar` with `BAr`, 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); + +impl Bar { + fn bar(self) { + self.foo() + //[current]~^ ERROR: no method named `foo` + } +} + +impl Bar { + 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 0000000000000..43e5935e375df --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr @@ -0,0 +1,21 @@ +error[E0307]: invalid `self` parameter type: Bar + --> $DIR/method_resolution3.rs:16:18 + | +LL | fn bar(self: Bar) { + | ^^^^^^^^ + | + = 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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0307]: invalid `self` parameter type: &Bar + --> $DIR/method_resolution3.rs:21:18 + | +LL | fn baz(self: &Bar) { + | ^^^^^^^^^ + | + = 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: Rc`, `self: Arc`, or `self: Pin

` (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 0000000000000..9272017cdf5d1 --- /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) { + | ^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `Foo == u32` + --> $DIR/method_resolution3.rs:21:18 + | +LL | fn baz(self: &Bar) { + | ^^^^^^^^^ 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 0000000000000..447f3144b822c --- /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); + +impl Bar { + fn bar(self: Bar) { + //[current]~^ ERROR: invalid `self` parameter + //[next]~^^ ERROR: type mismatch resolving `Foo == u32` + self.foo() + } + fn baz(self: &Bar) { + //[current]~^ ERROR: invalid `self` parameter + //[next]~^^ ERROR: type mismatch resolving `Foo == u32` + self.foo() + } +} + +impl Bar { + 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 0000000000000..30650dd070f94 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr @@ -0,0 +1,21 @@ +error[E0307]: invalid `self` parameter type: Bar + --> $DIR/method_resolution4.rs:21:18 + | +LL | fn foo(self: Bar) { + | ^^^^^^^^ + | + = 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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0307]: invalid `self` parameter type: &Bar + --> $DIR/method_resolution4.rs:27:20 + | +LL | fn foomp(self: &Bar) { + | ^^^^^^^^^ + | + = 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: Rc`, `self: Arc`, or `self: Pin

` (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 0000000000000..815fb8eef7cc3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr @@ -0,0 +1,34 @@ +error[E0284]: type annotations needed: cannot satisfy `_ == Foo` + --> $DIR/method_resolution4.rs:16:12 + | +LL | fn bar(self) {} + | ^^^^ cannot satisfy `_ == Foo` + +error[E0284]: type annotations needed: cannot satisfy `_ == Foo` + --> $DIR/method_resolution4.rs:21:12 + | +LL | fn foo(self: Bar) { + | ^^^^ cannot satisfy `_ == Foo` + +error[E0284]: type annotations needed: cannot satisfy `_ == Foo` + --> $DIR/method_resolution4.rs:27:14 + | +LL | fn foomp(self: &Bar) { + | ^^^^ cannot satisfy `_ == Foo` + +error[E0271]: type mismatch resolving `u32 == Foo` + --> $DIR/method_resolution4.rs:21:18 + | +LL | fn foo(self: Bar) { + | ^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `u32 == Foo` + --> $DIR/method_resolution4.rs:27:20 + | +LL | fn foomp(self: &Bar) { + | ^^^^^^^^^ types differ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0271, E0284. +For more information about an 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 0000000000000..50b4f77919a9e --- /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)] + +type Foo = impl Copy; + +#[derive(Copy, Clone)] +struct Bar(T); + +impl Bar { + fn bar(self) {} + //[next]~^ ERROR: type annotations needed: cannot satisfy `_ == Foo` +} + +impl Bar { + fn foo(self: Bar) { + //[current]~^ ERROR: invalid `self` parameter + //[next]~^^ ERROR: type annotations needed: cannot satisfy `_ == Foo` + //[next]~| ERROR: type mismatch resolving `u32 == Foo` + self.bar() + } + fn foomp(self: &Bar) { + //[current]~^ ERROR: invalid `self` parameter + //[next]~^^ ERROR: type annotations needed: cannot satisfy `_ == Foo` + //[next]~| ERROR: type mismatch resolving `u32 == Foo` + self.bar() + } +} + +fn foo() -> Foo { + 42_u32 +} + +fn main() {} 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 0000000000000..2617ce124c105 --- /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 0000000000000..9e44cb716b717 --- /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. + +//@[current] check-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +#![feature(type_alias_impl_trait)] + +pub struct Foo { + bar: Tait, +} + +type Tait = impl Iterator; + +impl Foo { + pub fn new() -> Foo { + Foo { bar: std::iter::empty() } + } + + fn foo(&mut self) { + self.bar.next().unwrap(); + //[next]~^ ERROR: type annotations needed + } +} + +fn main() {} From 1b71133c54e62f6779ea2a28983cd3315eb79dff Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Apr 2024 11:37:09 +0000 Subject: [PATCH 3/4] Method resolution constrains hidden types instead of rejecting method candidates --- .../src/obligation_forest/mod.rs | 5 ++- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../rustc_hir_typeck/src/method/confirm.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- tests/ui/impl-trait/issues/issue-70877.rs | 4 +- tests/ui/impl-trait/issues/issue-70877.stderr | 2 +- .../method-resolution.current.stderr | 36 ---------------- tests/ui/impl-trait/method-resolution.rs | 9 ++-- tests/ui/impl-trait/method-resolution2.rs | 2 +- .../method-resolution3.current.stderr | 43 ++++++------------- .../impl-trait/method-resolution3.next.stderr | 2 +- tests/ui/impl-trait/method-resolution3.rs | 4 +- .../method-resolution4.current.stderr | 16 +++++++ .../impl-trait/method-resolution4.next.stderr | 4 +- tests/ui/impl-trait/method-resolution4.rs | 3 +- tests/ui/methods/opaque_param_in_ufc.rs | 6 +-- tests/ui/methods/opaque_param_in_ufc.stderr | 36 ---------------- .../method_resolution2.current.stderr | 36 ---------------- .../method_resolution2.rs | 6 +-- ...on_trait_method_from_opaque.current.stderr | 15 +++++++ ...ution_trait_method_from_opaque.next.stderr | 2 +- ...hod_resolution_trait_method_from_opaque.rs | 3 +- 22 files changed, 71 insertions(+), 169 deletions(-) delete mode 100644 tests/ui/impl-trait/method-resolution.current.stderr create mode 100644 tests/ui/impl-trait/method-resolution4.current.stderr delete mode 100644 tests/ui/methods/opaque_param_in_ufc.stderr delete mode 100644 tests/ui/type-alias-impl-trait/method_resolution2.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index a47908648ba16..0352c085063e2 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -359,7 +359,10 @@ impl ObligationForest { Entry::Vacant(v) => { let obligation_tree_id = match parent { Some(parent_index) => self.nodes[parent_index].obligation_tree_id, - None => self.obligation_tree_id_generator.next().unwrap(), + // FIXME(type_alias_impl_trait): with `#[defines]` attributes required to define hidden + // types we can convert this back to a `next` method call, as this function shouldn't be + // defining a hidden type anyway. + None => Iterator::next(&mut self.obligation_tree_id_generator).unwrap(), }; let already_failed = parent.is_some() diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2580179ce5bf3..db161a6e9ccca 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1448,7 +1448,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args)); let self_ty = self.normalize(span, self_ty); match self.at(&self.misc(span), self.param_env).eq( - DefineOpaqueTypes::No, + DefineOpaqueTypes::Yes, impl_ty, self_ty, ) { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 36860e446fc2b..8965597e9f28d 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -499,7 +499,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { args, })), ); - match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::No, method_self_ty, self_ty) { + match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::Yes, method_self_ty, self_ty) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 28e17e1de36c3..265bd55436a4f 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1488,7 +1488,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.probe(|_| { // First check that the self type can be related. let sub_obligations = match self.at(&ObligationCause::dummy(), self.param_env).sup( - DefineOpaqueTypes::No, + DefineOpaqueTypes::Yes, probe.xform_self_ty, self_ty, ) { diff --git a/tests/ui/impl-trait/issues/issue-70877.rs b/tests/ui/impl-trait/issues/issue-70877.rs index df7722986744d..76cd7291a7c40 100644 --- a/tests/ui/impl-trait/issues/issue-70877.rs +++ b/tests/ui/impl-trait/issues/issue-70877.rs @@ -27,7 +27,9 @@ fn ham() -> Foo { fn oof(_: Foo) -> impl std::fmt::Debug { let mut bar = ham(); - let func = bar.next().unwrap(); + // Need to UFC invoke `Iterator::next`, + // as otherwise the hidden type gets constrained to `&mut _` + let func = Iterator::next(&mut bar).unwrap(); return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type } diff --git a/tests/ui/impl-trait/issues/issue-70877.stderr b/tests/ui/impl-trait/issues/issue-70877.stderr index 274139f01d087..804718c0fae61 100644 --- a/tests/ui/impl-trait/issues/issue-70877.stderr +++ b/tests/ui/impl-trait/issues/issue-70877.stderr @@ -1,5 +1,5 @@ error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/issue-70877.rs:31:12 + --> $DIR/issue-70877.rs:33:12 | LL | return func(&"oof"); | ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope diff --git a/tests/ui/impl-trait/method-resolution.current.stderr b/tests/ui/impl-trait/method-resolution.current.stderr deleted file mode 100644 index 6d10693c8933b..0000000000000 --- a/tests/ui/impl-trait/method-resolution.current.stderr +++ /dev/null @@ -1,36 +0,0 @@ -error[E0599]: no method named `bar` found for struct `Bar` in the current scope - --> $DIR/method-resolution.rs:23:11 - | -LL | struct Bar(T); - | ------------- method `bar` not found for this struct -... -LL | x.bar(); - | ^^^ method not found in `Bar` - | - = note: the method was found for - - `Bar` - -error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}` - --> $DIR/method-resolution.rs:19:24 - | -LL | fn foo(x: bool) -> Bar { - | ^^^^^^^^^^ - | -note: ...which requires type-checking `foo`... - --> $DIR/method-resolution.rs:23:9 - | -LL | x.bar(); - | ^ - = note: ...which requires evaluating trait selection obligation `Bar: 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 { - | ^^^^^^^^^^ - = 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 index 07618aa64085d..60fbacd86462b 100644 --- a/tests/ui/impl-trait/method-resolution.rs +++ b/tests/ui/impl-trait/method-resolution.rs @@ -1,10 +1,9 @@ -//! 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. +//! Since there is only one possible `bar` method, we invoke it and subsequently +//! constrain `foo`'s RPIT to `u32`. //@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass trait Trait {} @@ -17,11 +16,9 @@ impl Bar { } fn foo(x: bool) -> Bar { - //[current]~^ ERROR: cycle detected if x { let x = foo(false); x.bar(); - //[current]~^ ERROR: no method named `bar` found } todo!() } diff --git a/tests/ui/impl-trait/method-resolution2.rs b/tests/ui/impl-trait/method-resolution2.rs index 2930b42b8bca0..88d4f3d9896c7 100644 --- a/tests/ui/impl-trait/method-resolution2.rs +++ b/tests/ui/impl-trait/method-resolution2.rs @@ -1,5 +1,5 @@ //! 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. +//! `i32` is the only type that satisfies the RPIT's trait bounds. //@ revisions: current next //@[next] compile-flags: -Znext-solver diff --git a/tests/ui/impl-trait/method-resolution3.current.stderr b/tests/ui/impl-trait/method-resolution3.current.stderr index 7407b489e324f..87dd862ef8f4f 100644 --- a/tests/ui/impl-trait/method-resolution3.current.stderr +++ b/tests/ui/impl-trait/method-resolution3.current.stderr @@ -1,37 +1,20 @@ -error[E0599]: no method named `bar` found for struct `Bar` in the current scope - --> $DIR/method-resolution3.rs:22:11 +error[E0034]: multiple applicable items in scope + --> $DIR/method-resolution3.rs:21:11 | -LL | struct Bar(T); - | ------------- method `bar` not found for this struct -... LL | x.bar(); - | ^^^ method not found in `Bar` + | ^^^ multiple `bar` found | - = note: the method was found for - - `Bar` - - `Bar` - -error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}` - --> $DIR/method-resolution3.rs:18:24 - | -LL | fn foo(x: bool) -> Bar { - | ^^^^^^^^^^ +note: candidate #1 is defined in an impl for the type `Bar` + --> $DIR/method-resolution3.rs:15:5 | -note: ...which requires type-checking `foo`... - --> $DIR/method-resolution3.rs:22:9 - | -LL | x.bar(); - | ^ - = note: ...which requires evaluating trait selection obligation `Bar: 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 bar(self) {} + | ^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Bar` + --> $DIR/method-resolution3.rs:11:5 | -LL | fn foo(x: bool) -> Bar { - | ^^^^^^^^^^ - = 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 +LL | fn bar(self) {} + | ^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0391, E0599. -For more information about an error, try `rustc --explain E0391`. +For more information about this error, try `rustc --explain E0034`. diff --git a/tests/ui/impl-trait/method-resolution3.next.stderr b/tests/ui/impl-trait/method-resolution3.next.stderr index 53b77c620ba0e..87dd862ef8f4f 100644 --- a/tests/ui/impl-trait/method-resolution3.next.stderr +++ b/tests/ui/impl-trait/method-resolution3.next.stderr @@ -1,5 +1,5 @@ error[E0034]: multiple applicable items in scope - --> $DIR/method-resolution3.rs:22:11 + --> $DIR/method-resolution3.rs:21:11 | LL | x.bar(); | ^^^ multiple `bar` found diff --git a/tests/ui/impl-trait/method-resolution3.rs b/tests/ui/impl-trait/method-resolution3.rs index 8474e2da7dbb9..8c47ef4fc75c7 100644 --- a/tests/ui/impl-trait/method-resolution3.rs +++ b/tests/ui/impl-trait/method-resolution3.rs @@ -16,12 +16,10 @@ impl Bar { } fn foo(x: bool) -> Bar { - //[current]~^ ERROR: cycle if x { let x = foo(false); x.bar(); - //[current]~^ ERROR: no method named `bar` - //[next]~^^ ERROR: multiple applicable items in scope + //~^ ERROR: multiple applicable items in scope } todo!() } diff --git a/tests/ui/impl-trait/method-resolution4.current.stderr b/tests/ui/impl-trait/method-resolution4.current.stderr new file mode 100644 index 0000000000000..d87fda55d7204 --- /dev/null +++ b/tests/ui/impl-trait/method-resolution4.current.stderr @@ -0,0 +1,16 @@ +error[E0308]: mismatched types + --> $DIR/method-resolution4.rs:15:5 + | +LL | std::iter::empty() + | ^^^^^^^^^^^^^^^^^^ expected `&mut _`, found `Empty<_>` + | + = note: expected mutable reference `&mut _` + found struct `std::iter::Empty<_>` +help: consider mutably borrowing here + | +LL | &mut std::iter::empty() + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr index b48de0af3579d..41e914c62f37d 100644 --- a/tests/ui/impl-trait/method-resolution4.next.stderr +++ b/tests/ui/impl-trait/method-resolution4.next.stderr @@ -1,11 +1,11 @@ error[E0282]: type annotations needed - --> $DIR/method-resolution4.rs:13:9 + --> $DIR/method-resolution4.rs:12:9 | LL | foo(false).next().unwrap(); | ^^^^^^^^^^ cannot infer type error[E0308]: mismatched types - --> $DIR/method-resolution4.rs:16:5 + --> $DIR/method-resolution4.rs:15:5 | LL | fn foo(b: bool) -> impl Iterator { | ------------------------ the expected opaque type diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs index 3578db7cb55f3..8c6ff6ee9c894 100644 --- a/tests/ui/impl-trait/method-resolution4.rs +++ b/tests/ui/impl-trait/method-resolution4.rs @@ -4,7 +4,6 @@ //! variable, but get a type mismatch when comparing `&mut _` with //! `std::iter::Empty`. -//@[current] check-pass //@ revisions: current next //@[next] compile-flags: -Znext-solver @@ -14,7 +13,7 @@ fn foo(b: bool) -> impl Iterator { //[next]~^ type annotations needed } std::iter::empty() - //[next]~^ mismatched types + //~^ mismatched types } fn main() {} diff --git a/tests/ui/methods/opaque_param_in_ufc.rs b/tests/ui/methods/opaque_param_in_ufc.rs index a4b27a0131fd0..b170e6805f646 100644 --- a/tests/ui/methods/opaque_param_in_ufc.rs +++ b/tests/ui/methods/opaque_param_in_ufc.rs @@ -1,4 +1,7 @@ #![feature(type_alias_impl_trait)] + +//@ check-pass + struct Foo(T); impl Foo { @@ -15,14 +18,11 @@ fn bar() -> Bar { impl Foo { fn foo() -> Bar { Self::method(); - //~^ ERROR: no function or associated item named `method` found for struct `Foo` Foo::::method(); - //~^ ERROR: no function or associated item named `method` found for struct `Foo` let x = Foo(bar()); Foo::method2(x); let x = Self(bar()); Self::method2(x); - //~^ ERROR: no function or associated item named `method2` found for struct `Foo` todo!() } } diff --git a/tests/ui/methods/opaque_param_in_ufc.stderr b/tests/ui/methods/opaque_param_in_ufc.stderr deleted file mode 100644 index 7e5bbbac8a9ab..0000000000000 --- a/tests/ui/methods/opaque_param_in_ufc.stderr +++ /dev/null @@ -1,36 +0,0 @@ -error[E0599]: no function or associated item named `method` found for struct `Foo` in the current scope - --> $DIR/opaque_param_in_ufc.rs:17:15 - | -LL | struct Foo(T); - | ------------- function or associated item `method` not found for this struct -... -LL | Self::method(); - | ^^^^^^ function or associated item not found in `Foo` - | - = note: the function or associated item was found for - - `Foo` - -error[E0599]: no function or associated item named `method` found for struct `Foo` in the current scope - --> $DIR/opaque_param_in_ufc.rs:19:21 - | -LL | struct Foo(T); - | ------------- function or associated item `method` not found for this struct -... -LL | Foo::::method(); - | ^^^^^^ function or associated item not found in `Foo` - | - = note: the function or associated item was found for - - `Foo` - -error[E0599]: no function or associated item named `method2` found for struct `Foo` in the current scope - --> $DIR/opaque_param_in_ufc.rs:24:15 - | -LL | struct Foo(T); - | ------------- function or associated item `method2` not found for this struct -... -LL | Self::method2(x); - | ^^^^^^^ function or associated item not found in `Foo` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr deleted file mode 100644 index e68ea70a8ef48..0000000000000 --- a/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr +++ /dev/null @@ -1,36 +0,0 @@ -error[E0599]: no method named `foo` found for struct `Bar` in the current scope - --> $DIR/method_resolution2.rs:17:14 - | -LL | struct Bar(T); - | ------------- method `foo` not found for this struct -... -LL | self.foo() - | ^^^ method not found in `Bar` - | - = note: the method was found for - - `Bar` - -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 `::bar`... - --> $DIR/method_resolution2.rs:17:9 - | -LL | self.foo() - | ^^^^ - = note: ...which requires evaluating trait selection obligation `Bar: 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 index bb747246bf672..00a89f290de40 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution2.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution2.rs @@ -1,21 +1,19 @@ -//! check that we do not unify `Bar` with `BAr`, even though the +//! check that we do unify `Bar` with `Bar`, as the //! `foo` method call can be resolved unambiguously by doing so. //@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass #![feature(type_alias_impl_trait)] type Foo = impl Sized; -//[current]~^ ERROR: cycle struct Bar(T); impl Bar { fn bar(self) { self.foo() - //[current]~^ ERROR: no method named `foo` } } 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 0000000000000..3b8f0bc5a5858 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr @@ -0,0 +1,15 @@ +error[E0284]: type annotations needed + --> $DIR/method_resolution_trait_method_from_opaque.rs:25:18 + | +LL | self.bar.next().unwrap(); + | ^^^^ + | + = note: cannot satisfy `<_ as Iterator>::Item == _` +help: try using a fully qualified path to specify the expected types + | +LL | <_ as Iterator>::next(self.bar).unwrap(); + | ++++++++++++++++++++++ ~ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. 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 index 2617ce124c105..8e6cb8b4d41a8 100644 --- 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 @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 + --> $DIR/method_resolution_trait_method_from_opaque.rs:25:9 | LL | self.bar.next().unwrap(); | ^^^^^^^^ cannot infer type 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 index 9e44cb716b717..9a3ddf629f2c8 100644 --- 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 @@ -5,7 +5,6 @@ //! 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. -//@[current] check-pass //@ revisions: current next //@[next] compile-flags: -Znext-solver @@ -24,7 +23,7 @@ impl Foo { fn foo(&mut self) { self.bar.next().unwrap(); - //[next]~^ ERROR: type annotations needed + //~^ ERROR: type annotations needed } } From dc55e278aca2ff8f426169a73a7de36f7e9a4dc7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 16 Apr 2024 10:49:45 +0000 Subject: [PATCH 4/4] Fix breaking change in old solver --- compiler/rustc_hir_typeck/src/method/probe.rs | 34 +++++++++++++------ compiler/rustc_middle/src/traits/query.rs | 2 +- .../method-resolution4.current.stderr | 16 --------- .../impl-trait/method-resolution4.next.stderr | 4 +-- tests/ui/impl-trait/method-resolution4.rs | 3 +- ...on_trait_method_from_opaque.current.stderr | 15 -------- ...ution_trait_method_from_opaque.next.stderr | 2 +- ...hod_resolution_trait_method_from_opaque.rs | 3 +- 8 files changed, 31 insertions(+), 48 deletions(-) delete mode 100644 tests/ui/impl-trait/method-resolution4.current.stderr delete mode 100644 tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 265bd55436a4f..53cf30673a907 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1473,6 +1473,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + #[instrument(level = "trace", skip(self, possibly_unsatisfied_predicates), ret)] fn consider_probe( &self, self_ty: Ty<'tcx>, @@ -1483,20 +1484,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { Option>, )>, ) -> ProbeResult { - debug!("consider_probe: self_ty={:?} probe={:?}", self_ty, probe); - self.probe(|_| { // First check that the self type can be related. - let sub_obligations = match self.at(&ObligationCause::dummy(), self.param_env).sup( - DefineOpaqueTypes::Yes, - probe.xform_self_ty, - self_ty, - ) { - Ok(InferOk { obligations, value: () }) => obligations, - Err(err) => { - debug!("--> cannot relate self-types {:?}", err); - return ProbeResult::NoMatch; + let sub_obligations = match self_ty.kind() { + // HACK: opaque types will match anything for which their bounds hold. + // Thus we need to prevent them from trying to match the `&_` autoref + // candidates that get created for `&self` trait methods. + ty::Alias(ty::Opaque, alias_ty) + if self.infcx.can_define_opaque_ty(alias_ty.def_id) => + { + if !probe.xform_self_ty.is_ty_var() { + return ProbeResult::NoMatch; + } + vec![] } + _ => match self.at(&ObligationCause::dummy(), self.param_env).sup( + DefineOpaqueTypes::Yes, + probe.xform_self_ty, + self_ty, + ) { + Ok(InferOk { obligations, value: () }) => obligations, + Err(err) => { + debug!("--> cannot relate self-types {:?}", err); + return ProbeResult::NoMatch; + } + }, }; let mut result = ProbeResult::Match; diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 12e4f70ba5751..aab68b2dd60ce 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -162,7 +162,7 @@ pub struct CandidateStep<'tcx> { #[derive(Copy, Clone, Debug, HashStable)] pub struct MethodAutoderefStepsResult<'tcx> { - /// The valid autoderef steps that could be find. + /// The valid autoderef steps that could be found. pub steps: &'tcx [CandidateStep<'tcx>], /// If Some(T), a type autoderef reported an error on. pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>, diff --git a/tests/ui/impl-trait/method-resolution4.current.stderr b/tests/ui/impl-trait/method-resolution4.current.stderr deleted file mode 100644 index d87fda55d7204..0000000000000 --- a/tests/ui/impl-trait/method-resolution4.current.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/method-resolution4.rs:15:5 - | -LL | std::iter::empty() - | ^^^^^^^^^^^^^^^^^^ expected `&mut _`, found `Empty<_>` - | - = note: expected mutable reference `&mut _` - found struct `std::iter::Empty<_>` -help: consider mutably borrowing here - | -LL | &mut std::iter::empty() - | ++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr index 41e914c62f37d..b48de0af3579d 100644 --- a/tests/ui/impl-trait/method-resolution4.next.stderr +++ b/tests/ui/impl-trait/method-resolution4.next.stderr @@ -1,11 +1,11 @@ error[E0282]: type annotations needed - --> $DIR/method-resolution4.rs:12:9 + --> $DIR/method-resolution4.rs:13:9 | LL | foo(false).next().unwrap(); | ^^^^^^^^^^ cannot infer type error[E0308]: mismatched types - --> $DIR/method-resolution4.rs:15:5 + --> $DIR/method-resolution4.rs:16:5 | LL | fn foo(b: bool) -> impl Iterator { | ------------------------ the expected opaque type diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs index 8c6ff6ee9c894..91884eb59fd63 100644 --- a/tests/ui/impl-trait/method-resolution4.rs +++ b/tests/ui/impl-trait/method-resolution4.rs @@ -6,6 +6,7 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver +//@[current] check-pass fn foo(b: bool) -> impl Iterator { if b { @@ -13,7 +14,7 @@ fn foo(b: bool) -> impl Iterator { //[next]~^ type annotations needed } std::iter::empty() - //~^ mismatched types + //[next]~^ mismatched types } 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 deleted file mode 100644 index 3b8f0bc5a5858..0000000000000 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0284]: type annotations needed - --> $DIR/method_resolution_trait_method_from_opaque.rs:25:18 - | -LL | self.bar.next().unwrap(); - | ^^^^ - | - = note: cannot satisfy `<_ as Iterator>::Item == _` -help: try using a fully qualified path to specify the expected types - | -LL | <_ as Iterator>::next(self.bar).unwrap(); - | ++++++++++++++++++++++ ~ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0284`. 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 index 8e6cb8b4d41a8..2617ce124c105 100644 --- 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 @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/method_resolution_trait_method_from_opaque.rs:25:9 + --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 | LL | self.bar.next().unwrap(); | ^^^^^^^^ cannot infer type 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 index 9a3ddf629f2c8..3635479f7d85f 100644 --- 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 @@ -7,6 +7,7 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver +//@[current] check-pass #![feature(type_alias_impl_trait)] @@ -23,7 +24,7 @@ impl Foo { fn foo(&mut self) { self.bar.next().unwrap(); - //~^ ERROR: type annotations needed + //[next]~^ ERROR: type annotations needed } }