forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reject generic self types using impl defid: do not merge.
The RFC for arbitrary self types v2 declares that we should reject "generic" self types. This commit does so. The definition of "generic" was unclear in the RFC, but has been explored in rust-lang#129147 and the conclusion is that "generic" means any `self` type which is a type parameter defined on the method itself, or references to such a type. This approach was chosen because other definitions of "generic" don't work. Specifically, * we can't filter out generic type _arguments_, because that would filter out Rc<Self> and all the other types of smart pointer we want to support; * we can't filter out all type params, because Self itself is a type param, and because existing Rust code depends on other type params declared on the type (as opposed to the method). This PR is a second attempt at achieving this, based on producing a new well-formedness checking context which is only aware of the type params of the impl block, not of the method itself. It doesn't currently work because it turns out we do need some method params under some circumstances, but raising it for completeness. This PR adds lots of extra tests to arbitrary-self-from-method-substs. Most of these are ways to trigger a "type mismatch" error which https://github.com/rust-lang/rust/blob/9b82580c7347f800c2550e6719e4218a60a80b28/compiler/rustc_hir_typeck/src/method/confirm.rs#L519 hopes can be minimized by filtering out generics in this way. We remove a FIXME from confirm.rs suggesting that we make this change. It's still possible to cause type mismatch errors, and a subsequent PR may be able to improve diagnostics in this area, but it's harder to cause these errors without contrived uses of the turbofish. This is a part of the arbitrary self types v2 project, rust-lang/rfcs#3519 rust-lang#44874 r? @wesleywiser
- Loading branch information
Showing
10 changed files
with
486 additions
and
100 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
162 changes: 158 additions & 4 deletions
162
tests/ui/self/arbitrary-self-from-method-substs.default.stderr
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 |
---|---|---|
@@ -1,14 +1,168 @@ | ||
error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature | ||
--> $DIR/arbitrary-self-from-method-substs.rs:8:43 | ||
error[E0799]: invalid generic `self` parameter type: `R` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:9:43 | ||
| | ||
LL | fn get<R: Deref<Target = Self>>(self: R) -> u32 { | ||
| ^ | ||
| | ||
= note: type of `self` must not be a method generic parameter type | ||
= help: use a concrete type such as `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[E0799]: invalid generic `self` parameter type: `&R` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:13:44 | ||
| | ||
LL | fn get1<R: Deref<Target = Self>>(self: &R) -> u32 { | ||
| ^^ | ||
| | ||
= note: type of `self` must not be a method generic parameter type | ||
= help: use a concrete type such as `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[E0799]: invalid generic `self` parameter type: `&mut R` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:17:44 | ||
| | ||
LL | fn get2<R: Deref<Target = Self>>(self: &mut R) -> u32 { | ||
| ^^^^^^ | ||
| | ||
= note: type of `self` must not be a method generic parameter type | ||
= help: use a concrete type such as `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[E0799]: invalid generic `self` parameter type: `Rc<R>` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:21:44 | ||
| | ||
LL | fn get3<R: Deref<Target = Self>>(self: std::rc::Rc<R>) -> u32 { | ||
| ^^^^^^^^^^^^^^ | ||
| | ||
= note: type of `self` must not be a method generic parameter type | ||
= help: use a concrete type such as `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[E0799]: invalid generic `self` parameter type: `&Rc<R>` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:25:44 | ||
| | ||
LL | fn get4<R: Deref<Target = Self>>(self: &std::rc::Rc<R>) -> u32 { | ||
| ^^^^^^^^^^^^^^^ | ||
| | ||
= note: type of `self` must not be a method generic parameter type | ||
= help: use a concrete type such as `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[E0799]: invalid generic `self` parameter type: `Rc<&R>` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:29:44 | ||
| | ||
LL | fn get5<R: Deref<Target = Self>>(self: std::rc::Rc<&R>) -> u32 { | ||
| ^^^^^^^^^^^^^^^ | ||
| | ||
= note: type of `self` must not be a method generic parameter type | ||
= help: use a concrete type such as `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[E0658]: `<FR as FindReceiver>::Receiver` cannot be used as the type of `self` without the `arbitrary_self_types` feature | ||
--> $DIR/arbitrary-self-from-method-substs.rs:33:37 | ||
| | ||
LL | fn get6<FR: FindReceiver>(self: FR::Receiver, other: FR) -> u32 { | ||
| ^^^^^^^^^^^^ | ||
| | ||
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information | ||
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable | ||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | ||
= 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 1 previous error | ||
error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature | ||
--> $DIR/arbitrary-self-from-method-substs.rs:61:18 | ||
| | ||
LL | fn get(self: R) {} | ||
| ^ | ||
| | ||
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information | ||
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable | ||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | ||
= 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[E0271]: type mismatch resolving `<Silly as FindReceiver>::Receiver == Foo` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:92:9 | ||
| | ||
LL | foo.get6(Silly); | ||
| ^^^^ type mismatch resolving `<Silly as FindReceiver>::Receiver == Foo` | ||
| | ||
note: expected this to be `Rc<Foo>` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:71:21 | ||
| | ||
LL | type Receiver = std::rc::Rc<Foo>; | ||
| ^^^^^^^^^^^^^^^^ | ||
= note: expected struct `Rc<Foo>` | ||
found struct `Foo` | ||
|
||
error[E0271]: type mismatch resolving `<Silly as FindReceiver>::Receiver == &Foo` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:96:9 | ||
| | ||
LL | foo.get6(Silly); | ||
| ^^^^ type mismatch resolving `<Silly as FindReceiver>::Receiver == &Foo` | ||
| | ||
note: expected this to be `Rc<Foo>` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:71:21 | ||
| | ||
LL | type Receiver = std::rc::Rc<Foo>; | ||
| ^^^^^^^^^^^^^^^^ | ||
= note: expected struct `Rc<Foo>` | ||
found reference `&Foo` | ||
|
||
error[E0599]: the method `get` exists for struct `Rc<Bar<_>>`, but its trait bounds were not satisfied | ||
--> $DIR/arbitrary-self-from-method-substs.rs:100:7 | ||
| | ||
LL | struct Bar<R>(std::marker::PhantomData<R>); | ||
| ------------- doesn't satisfy `Bar<_>: Deref` | ||
... | ||
LL | t.get(); | ||
| ^^^ method cannot be called on `Rc<Bar<_>>` due to unsatisfied trait bounds | ||
| | ||
note: the following trait bounds were not satisfied: | ||
`<&Bar<_> as Deref>::Target = Bar<&Bar<_>>` | ||
`<&Rc<Bar<_>> as Deref>::Target = Bar<&Rc<Bar<_>>>` | ||
`<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>` | ||
`<&mut Rc<Bar<_>> as Deref>::Target = Bar<&mut Rc<Bar<_>>>` | ||
`<Rc<Bar<_>> as Deref>::Target = Bar<Rc<Bar<_>>>` | ||
`Bar<_>: Deref` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:60:9 | ||
| | ||
LL | impl<R: std::ops::Deref<Target = Self>> Bar<R> { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ | ||
| | | | ||
| | unsatisfied trait bound introduced here | ||
| unsatisfied trait bound introduced here | ||
note: the trait `Deref` must be implemented | ||
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL | ||
= help: items from traits can only be used if the trait is implemented and in scope | ||
= note: the following trait defines an item `get`, perhaps you need to implement it: | ||
candidate #1: `SliceIndex` | ||
|
||
error[E0599]: the method `get` exists for reference `&Rc<Bar<_>>`, but its trait bounds were not satisfied | ||
--> $DIR/arbitrary-self-from-method-substs.rs:108:7 | ||
| | ||
LL | struct Bar<R>(std::marker::PhantomData<R>); | ||
| ------------- doesn't satisfy `Bar<_>: Deref` | ||
... | ||
LL | t.get(); | ||
| ^^^ method cannot be called on `&Rc<Bar<_>>` due to unsatisfied trait bounds | ||
| | ||
note: the following trait bounds were not satisfied: | ||
`<&&Rc<Bar<_>> as Deref>::Target = Bar<&&Rc<Bar<_>>>` | ||
`<&Bar<_> as Deref>::Target = Bar<&Bar<_>>` | ||
`<&Rc<Bar<_>> as Deref>::Target = Bar<&Rc<Bar<_>>>` | ||
`<&mut &Rc<Bar<_>> as Deref>::Target = Bar<&mut &Rc<Bar<_>>>` | ||
`<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>` | ||
`<&mut Rc<Bar<_>> as Deref>::Target = Bar<&mut Rc<Bar<_>>>` | ||
`<Rc<Bar<_>> as Deref>::Target = Bar<Rc<Bar<_>>>` | ||
`Bar<_>: Deref` | ||
--> $DIR/arbitrary-self-from-method-substs.rs:60:9 | ||
| | ||
LL | impl<R: std::ops::Deref<Target = Self>> Bar<R> { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ | ||
| | | | ||
| | unsatisfied trait bound introduced here | ||
| unsatisfied trait bound introduced here | ||
note: the trait `Deref` must be implemented | ||
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL | ||
= help: items from traits can only be used if the trait is implemented and in scope | ||
= note: the following trait defines an item `get`, perhaps you need to implement it: | ||
candidate #1: `SliceIndex` | ||
|
||
error: aborting due to 12 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0658`. | ||
Some errors have detailed explanations: E0271, E0599, E0658, E0799. | ||
For more information about an error, try `rustc --explain E0271`. |
Oops, something went wrong.