forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of rust-lang#123962 - oli-obk:define_opaque_types5, r=<try>
change method resolution to constrain hidden types instead of rejecting method candidates Some of these are in probes and may affect inference. This is therefore a breaking change. This allows new code to compile on stable: ```rust trait Trait {} impl Trait for u32 {} struct Bar<T>(T); impl Bar<u32> { fn foo(self) {} } fn foo(x: bool) -> Bar<impl Sized> { if x { let x = foo(false); x.foo(); //^ this used to not find the `foo` method, because while we did equate `x`'s type with possible candidates, we didn't allow opaque type inference while doing so } todo!() } ``` But it is also a breaking change, since `&self` and `&mut self` method calls on recursive RPIT function calls now constrain the hidden type to `&_` and `&mut _` respectively. This is not what users really expect or want from this, but there's way around this. r? `@compiler-errors` fixes rust-lang#121404 cc rust-lang#116652
- Loading branch information
Showing
33 changed files
with
580 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
error[E0599]: no method named `foo` found for struct `Bar` in the current scope | ||
--> $DIR/method-resolution.rs:22:11 | ||
| | ||
LL | struct Bar<T>(T); | ||
| ------------- method `foo` not found for this struct | ||
... | ||
LL | x.foo(); | ||
| ^^^ method not found in `Bar<impl Sized>` | ||
|
||
error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}` | ||
--> $DIR/method-resolution.rs:18:24 | ||
| | ||
LL | fn foo(x: bool) -> Bar<impl Sized> { | ||
| ^^^^^^^^^^ | ||
| | ||
note: ...which requires type-checking `foo`... | ||
--> $DIR/method-resolution.rs:22:9 | ||
| | ||
LL | x.foo(); | ||
| ^ | ||
= 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: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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
error[E0599]: no method named `foo` found for struct `Bar` in the current scope | ||
--> $DIR/method-resolution.rs:22:11 | ||
| | ||
LL | struct Bar<T>(T); | ||
| ------------- method `foo` not found for this struct | ||
... | ||
LL | x.foo(); | ||
| ^^^ method not found in `Bar<_>` | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0599`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
//! 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 | ||
|
||
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 | ||
if x { | ||
let x = foo(false); | ||
x.foo(); | ||
//~^ ERROR: no method named `foo` found | ||
} | ||
todo!() | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
error[E0599]: no method named `foo` found for struct `Bar` in the current scope | ||
--> $DIR/method-resolution3.rs:22:11 | ||
| | ||
LL | struct Bar<T>(T); | ||
| ------------- method `foo` not found for this struct | ||
... | ||
LL | x.foo(); | ||
| ^^^ method not found in `Bar<impl Sized>` | ||
|
||
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.foo(); | ||
| ^ | ||
= 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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
error[E0599]: no method named `foo` found for struct `Bar` in the current scope | ||
--> $DIR/method-resolution3.rs:22:11 | ||
| | ||
LL | struct Bar<T>(T); | ||
| ------------- method `foo` not found for this struct | ||
... | ||
LL | x.foo(); | ||
| ^^^ method not found in `Bar<_>` | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0599`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
//! 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.foo(); | ||
//~^ ERROR: no method named `foo` found | ||
} | ||
todo!() | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
error[E0282]: type annotations needed | ||
--> $DIR/method-resolution4.rs:12:9 | ||
| | ||
LL | foo(false).next().unwrap(); | ||
| ^^^^^^^^^^ cannot infer type | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/method-resolution4.rs:15: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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//! 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`. | ||
|
||
//@ 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() | ||
//~^ mismatched types | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.