-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tracking issue for RFC 3519: arbitrary_self_types
#44874
Comments
Why would you need this?
I'd rather define the trait different. Maybe like this:
In this case, Rc would be a trait type. If every generic type implemented a specific trait (this could be implemented automatically for generic types) this seems more understandable to me. |
This could only be allowed for For inherent methods, I can't |
This is still pending lang team decisions (I hope there will be at least 1 RFC) but I think it will only be allowed for trait method impls. |
You can't implement anything for |
So changes needed:
|
I’ll look into this. |
Note that this is only supported to work with trait methods (and trait impl methods), aka trait Foo {
fn foo(self: Rc<Self>);
}
impl Foo for () {
fn foo(self: Rc<Self>) {}
} and is NOT supposed to work for inherent impl methods: struct Foo;
impl Foo {
fn foo(self: Rc<Self>) {}
} |
I got caught in some more Stylo work that's gonna take a while, so if someone else wants to work on this in the meantime feel free. |
Is this supposed to allow any type as long as it involves trait MyStuff {
fn a(self: Option<Self>);
fn b(self: Result<Self, Self>);
fn c(self: (Self, Self, Self));
fn d(self: Box<Box<Self>>);
}
impl MyStuff for i32 {
...
}
Some(1).a(); // ok?
Ok(2).b(); // ok?
(3, 4, 5).c(); // ok?
(box box 6).d(); // ok? |
…ents, r=nikomatsakis Update comments referring to old check_method_self_type I was browsing the code base, trying to figure out how rust-lang#44874 could be implemented, and noticed some comments that were out of date and a bit misleading (`check_method_self_type` has since been renamed to `check_method_receiver`). Thought it would be an easy first contribution to Rust!
I've started working on this issue. You can see my progress on this branch |
@arielb1 You seem adamant that this should only be allowed for traits and not structs. Aside from method shadowing, are there other concerns? |
inherent impl methods are loaded based on the type. You shouldn't be able to add a method to |
That's it, if you write something like trait Foo {
fn bar(self: Rc<Self>);
} Then it can only be used if the trait If you write an inherent impl, then it can be called without having the trait in-scope, which means we have to be more careful to not allow these sorts of things. |
@arielb1 Can you give an example of what we want to avoid? I'm afraid I don't really see what the issue is. A method you define to take |
I've been trying to figure out how we can support dynamic dispatch with arbitrary self types. Basically we need a way to take a (1) is pretty straightforward: call The tough question is, how do we get the type @arielb1 @nikomatsakis any thoughts? |
Wait, why do you not want it work for inherent impl methods? Because of scoping? I'm confused. =) |
I do want to support that, but I expected it to be out of scope for this first cut. That is, I expected that if a trait uses anything other than |
I know, but I couldn't help looking into it, it's all very interesting to me :) |
We need some sort of "orphan rule" to at least prevent people from doing things like this: struct Foo;
impl Foo {
fn frobnicate<T>(self: Vec<T>, x: Self) { /* ... */ }
} Because then every crate in the world can call Maybe the best way to solve this would be to require I think that if we have the deref-back requirement, there's no problem with allowing inherent methods - we just need to change inherent method search a bit to also look at defids of derefs. So that's probably a better idea than restricting to trait methods only. Note that the struct Foo;
impl Tr for Foo {
fn frobnicate<A: Allocator+?Sized>(self: RcWithAllocator<Self, A>) { /* ... */ }
} Where an |
Are saying is that there would be a "conflicting symbols for architechture x86_64..." linker error?
I'm confused, are you still talking about |
The deref-back requirement is supposed to be for everything, not only object-safety. It prevents the problem when one person does struct MyType;
impl MyType {
fn foo<T>(self: Vec<(MyType, T)>) { /* ... */ }
} While another person does struct OurType;
impl OurType {
fn foo<T>(self: Vec<(T, OurType)>) {/* ... */ }
} And now you have a conflict on |
Rollup merge of rust-lang#134264 - adetaylor:weak-and-nonnull, r=compiler-errors Arbitrary self types v2: Weak & NonNull diagnostics This builds on top of rust-lang#134262 which is more urgent to review and merge first. I'll likely rebase this PR once that lands. This is the first part of the diagnostic enhancements planned for Arbitrary Self Types v2. Various types can be used as method receivers, such as `Rc<>`, `Box<>` and `Arc<>`. The arbitrary self types v2 work allows further types to be made method receivers by implementing the Receiver trait. With that in mind, it may come as a surprise to people when certain common types do not implement Receiver and thus cannot be used as a method receiver. The RFC for arbitrary self types v2 therefore proposes emitting specific lint hints for these cases: * `NonNull` * `Weak` * Raw pointers The code already emits a hint for this third case, in that it advises folks that the `arbitrary_self_types_pointers` feature may meet their need. This PR adds diagnostic hints for the `Weak` and `NonNull` cases. Tracking issue rust-lang#44874 r? `@wesleywiser`
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
commit c95bbb59a9b22f9b838b15d28319185c1c884329 upstream. The term "receiver" means that a type can be used as the type of `self`, and thus enables method call syntax `foo.bar()` instead of `Foo::bar(foo)`. Stable Rust as of today (1.81) enables a limited selection of types (primitives and types in std, e.g. `Box` and `Arc`) to be used as receivers, while custom types cannot. We want the kernel `Arc` type to have the same functionality as the Rust std `Arc`, so we use the `Receiver` trait (gated behind `receiver_trait` unstable feature) to gain the functionality. The `arbitrary_self_types` RFC [1] (tracking issue [2]) is accepted and it will allow all types that implement a new `Receiver` trait (different from today's unstable trait) to be used as receivers. This trait will be automatically implemented for all `Deref` types, which include our `Arc` type, so we no longer have to opt-in to be used as receiver. To prepare us for the change, remove the `Receiver` implementation and the associated feature. To still allow `Arc` and others to be used as method receivers, turn on `arbitrary_self_types` feature instead. This feature gate is introduced in 1.23.0. It used to enable both `Deref` types and raw pointer types to be used as receivers, but the latter is now split into a different feature gate in Rust 1.83 nightly. We do not need receivers on raw pointers so this change would not affect us and usage of `arbitrary_self_types` feature would work for all Rust versions that we support (>=1.78). Cc: Adrian Taylor <ade@hohum.me.uk> Link: rust-lang/rfcs#3519 [1] Link: rust-lang/rust#44874 [2] Signed-off-by: Gary Guo <gary@garyguo.net> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20240915132734.1653004-1-gary@garyguo.net Signed-off-by: Miguel Ojeda <ojeda@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Another update relative to the plan:
Assumptions made during landing the main PR which we should consider before stabilization (if you want to discuss these, please open a new issue instead of discussing here). All of these are related to the deshadowing algorithm, which attempts to spot cases where an outer smart pointer type adds a new method that might "shadow" or override some method in a referent. As a reminder, the complexity here is that the shadower and shadowed might take
|
A further update on item 9, documentation. All the following PRs are draft and not yet for review, but linking them from here for awareness:
In the process of preparing these docs, I found a creative, cunning and implausible way to trigger the new deshadowing code without enabling the |
Arbitrary self types v2: roll loop. Just for slightly more concise code - no functional changes. r? `@wesleywiser` Part of rust-lang#44874
Rollup merge of rust-lang#134521 - adetaylor:roll-loop, r=wesleywiser Arbitrary self types v2: roll loop. Just for slightly more concise code - no functional changes. r? `@wesleywiser` Part of rust-lang#44874
… r=wesleywiser Arbitrary self types v2: niche deshadowing test Arbitrary self types v2 attempts to detect cases where methods in an "outer" type (e.g. a smart pointer) might "shadow" methods in the referent. There are a couple of cases where the current code makes no attempt to detect such shadowing. Both of these cases only apply if other unstable features are enabled. Add a test, mostly for illustrative purposes, so we can see the shadowing cases that can occur. Part of rust-lang#44874 r? `@wesleywiser`
… r=wesleywiser Arbitrary self types v2: niche deshadowing test Arbitrary self types v2 attempts to detect cases where methods in an "outer" type (e.g. a smart pointer) might "shadow" methods in the referent. There are a couple of cases where the current code makes no attempt to detect such shadowing. Both of these cases only apply if other unstable features are enabled. Add a test, mostly for illustrative purposes, so we can see the shadowing cases that can occur. Part of rust-lang#44874 r? ``@wesleywiser``
Arbitrary self types v2: no deshadow pre feature. The arbitrary self types v2 work introduces a check for shadowed methods, whereby a method in some "outer" smart pointer type may called in preference to a method in the inner referent. This is bad if the outer pointer adds a method later, as it may change behavior, so we ensure we error in this circumstance. It was intended that this new shadowing detection system only comes into play for users who enable the `arbitrary_self_types` feature (or of course everyone later if it's stabilized). It was believed that the new deshadowing code couldn't be reached without building the custom smart pointers that `arbitrary_self_types` enables, and therefore there was no risk of this code impacting existing users. However, it turns out that cunning use of `Pin::get_ref` can cause this type of shadowing error to be emitted now. This commit adds a test for this case. As we want this test to pass without arbitrary_self_types, but fail with it, I've split it into two files (one with run-pass and one without). If there's a better way I can amend it. Part of rust-lang#44874 r? ``@wesleywiser``
Just for visibility to the team, see my comment on the PR for this in The Book. Short version: not yet sure if it fits in The Book at all, and if it does we’ll need to think about where and how to make it fit! Happy to discuss further… but probably after the holidays! |
… r=wesleywiser Arbitrary self types v2: niche deshadowing test Arbitrary self types v2 attempts to detect cases where methods in an "outer" type (e.g. a smart pointer) might "shadow" methods in the referent. There are a couple of cases where the current code makes no attempt to detect such shadowing. Both of these cases only apply if other unstable features are enabled. Add a test, mostly for illustrative purposes, so we can see the shadowing cases that can occur. Part of rust-lang#44874 r? ```@wesleywiser```
Arbitrary self types v2: no deshadow pre feature. The arbitrary self types v2 work introduces a check for shadowed methods, whereby a method in some "outer" smart pointer type may called in preference to a method in the inner referent. This is bad if the outer pointer adds a method later, as it may change behavior, so we ensure we error in this circumstance. It was intended that this new shadowing detection system only comes into play for users who enable the `arbitrary_self_types` feature (or of course everyone later if it's stabilized). It was believed that the new deshadowing code couldn't be reached without building the custom smart pointers that `arbitrary_self_types` enables, and therefore there was no risk of this code impacting existing users. However, it turns out that cunning use of `Pin::get_ref` can cause this type of shadowing error to be emitted now. This commit adds a test for this case. As we want this test to pass without arbitrary_self_types, but fail with it, I've split it into two files (one with run-pass and one without). If there's a better way I can amend it. Part of rust-lang#44874 r? ```@wesleywiser```
Rollup merge of rust-lang#134524 - adetaylor:getref, r=compiler-errors Arbitrary self types v2: no deshadow pre feature. The arbitrary self types v2 work introduces a check for shadowed methods, whereby a method in some "outer" smart pointer type may called in preference to a method in the inner referent. This is bad if the outer pointer adds a method later, as it may change behavior, so we ensure we error in this circumstance. It was intended that this new shadowing detection system only comes into play for users who enable the `arbitrary_self_types` feature (or of course everyone later if it's stabilized). It was believed that the new deshadowing code couldn't be reached without building the custom smart pointers that `arbitrary_self_types` enables, and therefore there was no risk of this code impacting existing users. However, it turns out that cunning use of `Pin::get_ref` can cause this type of shadowing error to be emitted now. This commit adds a test for this case. As we want this test to pass without arbitrary_self_types, but fail with it, I've split it into two files (one with run-pass and one without). If there's a better way I can amend it. Part of rust-lang#44874 r? ```@wesleywiser```
Rollup merge of rust-lang#134509 - adetaylor:niche-deshadowing-tests, r=wesleywiser Arbitrary self types v2: niche deshadowing test Arbitrary self types v2 attempts to detect cases where methods in an "outer" type (e.g. a smart pointer) might "shadow" methods in the referent. There are a couple of cases where the current code makes no attempt to detect such shadowing. Both of these cases only apply if other unstable features are enabled. Add a test, mostly for illustrative purposes, so we can see the shadowing cases that can occur. Part of rust-lang#44874 r? ```@wesleywiser```
…=compiler-errors,wesleywiser Arbitrary self types v2: main compiler changes This is the main PR in a series of PRs related to Arbitrary Self Types v2, tracked in #44874. Specifically this is step 7 of the plan [described here](rust-lang/rust#44874 (comment)), for [RFC 3519](rust-lang/rfcs#3519). Overall this PR: * Switches from the `Deref` trait to the new `Receiver` trait when the unstable `arbitrary_self_types` feature is enabled (the simple bit) * Introduces new algorithms to spot "shadowing"; that is, the case where a newly-added method in an outer smart pointer might end up overriding a pre-existing method in the pointee (the complex bit). Most of this bit was explored in [this earlier perf-testing PR](rust-lang/rust#127812 (comment)). * Lots of tests This should not break compatibility for: * Stable users, where it should have no effect * Users of the existing `arbitrary_self_types` feature (because we implement `Receiver` for `T: Deref`) _unless_ those folks have added methods which may shadow methods in inner types, which we no longer want to allow Subsequent PRs will add better diagnostics. It's probably easiest to review this commit-by-commit. r? `@wesleywiser`
…=wesleywiser Arbitrary self types v2: unstable doc updates. Document these two feature flags. Part of rust-lang#44874 .
Rollup merge of rust-lang#134525 - adetaylor:unstable-book-changes, r=wesleywiser Arbitrary self types v2: unstable doc updates. Document these two feature flags. Part of rust-lang#44874 .
Another periodic update:
Next steps:
|
This is the tracking issue for RFC 3519: Arbitrary self types v2.
The feature gate for this issue is
#![feature(arbitrary_self_types)]
.About tracking issues
Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Steps
Current plan is:
arbitrary_self_types_pointers
feature gateReceiver
trait -- currently being run through craterReceiver
trait without it doing anything.Receiver
trait, if thearbitrary_self_types
feature is enabled. The main event.!Sized
case and theNonNull
etc. cases.Unresolved Questions
None.
Notable for Stabilization
Related
Implementation history
TODO.
(Below follows content that predated the accepted Arbitrary Self Types v2 RFC.)
Object Safety
See #27941 (comment)
Handling of inference variables
Calling a method on
*const _
could now pick impls of the formBecause method dispatch wants to be "limited", this won't really work, and as with the existing situation on
&_
we should be emitting an "the type of this value must be known in this context" error.This feels like fairly standard inference breakage, but we need to check the impact of this before proceeding.
Safe virtual raw pointer methods
e.g. this is UB, so we might want to force the call
<dyn Foo as Foo>::bar
to be unsafe somehow - e.g. by not allowingdyn Foo
to be object safe unlessbar
was anunsafe fn
However, even today you could UB in safe code with
mem::size_of_val(foo)
on the above code, so this might not be actually a problem.More information
There's no reason the
self
syntax has to be restricted to&T
,&mut T
andBox<T>
, we should allow for more types there, e.g.The text was updated successfully, but these errors were encountered: