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.
Rollup merge of rust-lang#130098 - adetaylor:arbitrary-self-types-block-generics, r=wesleywiser Reject generic self types. 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 decides to make a new error code for this case, instead of reusing the existing E0307 error. This makes the code a bit more complex, but it seems we have an opportunity to provide specific diagnostics for this case so we should do so. This PR filters out generic self types whether or not the 'arbitrary self types' feature is enabled. However, it's believed that it can't have any effect on code which uses stable Rust, since there are no stable traits which can be used to indicate a valid generic receiver type, and thus it would have been impossible to write code which could trigger this new error case. It is however possible that this could break existing code which uses either of the unstable `arbitrary_self_types` or `receiver_trait` features. This breakage is intentional; as we move arbitrary self types towards stabilization we don't want to continue to support generic such types. 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
14 changed files
with
549 additions
and
57 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
The `self` parameter in a method has an invalid generic "receiver type". | ||
|
||
Erroneous code example: | ||
|
||
```compile_fail,E0801 | ||
struct Foo; | ||
impl Foo { | ||
fn foo<R: std::ops::Deref<Target=Self>>(self: R) {} | ||
} | ||
``` | ||
|
||
or alternatively, | ||
|
||
```compile_fail,E0801 | ||
struct Foo; | ||
impl Foo { | ||
fn foo(self: impl std::ops::Deref<Target=Self>) {} | ||
} | ||
``` | ||
|
||
Methods take a special first parameter, termed `self`. It's normal to | ||
use `self`, `&self` or `&mut self`, which are syntactic sugar for | ||
`self: Self`, `self: &Self`, and `self: &mut Self` respectively. | ||
But it's also possible to use more sophisticated types of `self` | ||
parameter, for instance `std::rc::Rc<Self>`. The set of allowable | ||
`Self` types is extensible using the nightly feature | ||
[Arbitrary self types][AST]. | ||
This will extend the valid set of `Self` types to anything which implements | ||
`std::ops::Deref<Target=Self>`, for example `Rc<Self>`, `Box<Self>`, or | ||
your own smart pointers that do the same. | ||
|
||
However, even with that feature, the `self` type must be concrete. | ||
Generic `self` types are not permitted. Specifically, a `self` type will | ||
be rejected if it is a type parameter defined on the method. | ||
|
||
These are OK: | ||
|
||
``` | ||
struct Foo; | ||
impl Foo { | ||
fn foo(self) {} | ||
fn foo2(self: std::rc::Rc<Self>) {} // or some other similar | ||
// smart pointer if you enable arbitrary self types and | ||
// the pointer implements Deref<Target=Self> | ||
} | ||
``` | ||
|
||
[AST]: https://doc.rust-lang.org/unstable-book/language-features/arbitrary-self-types.html |
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 |
---|---|---|
|
@@ -540,6 +540,7 @@ E0797: 0797, | |
E0798: 0798, | ||
E0799: 0799, | ||
E0800: 0800, | ||
E0801: 0801, | ||
); | ||
) | ||
} | ||
|
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
Oops, something went wrong.