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 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!
…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 |
Also, is the expectation that this If so, it seems like we'd probably end up recommending types that implementing If not, I think we shouldn't implement it for any non-fundamental containers, like |
Currently lifetimes cannot be elided when using struct A(u32);
impl A {
// compile error
pub fn value(self: &Arc<Self>) -> &u32 { &self.0 }
// ^ error: missing lifetime specifier. this function's return type contains a borrowed value, but there is no value for it to be borrowed from
// ok
pub fn value_lifetimed<'a>(self: &'a Arc<Self>) -> &'a u32 { &self.0 }
} And The Rust Reference says:
Should this rule also be expanded to arbitary self types? |
Is that a feature like UFCS(Uniform Function Call Syntax)? |
Has there been any discussion about |
What could be the reason I cannot get a receiver with an extra trait bound (e.g. struct Ptr<T: ?Sized + Send>(Box<T>);
// impls for Deref, CoerceUnsized and DispatchFromDyn
trait Trait: Send { fn ptr_wrapper(self: Ptr<Self>) -> i32; }
impl Trait for i32 { fn ptr_wrapper(self: Ptr<Self>) -> i32 { *self }}
fn main() {
let p = Ptr(Box::new(5)) as Ptr<dyn Trait>;
assert_eq!(p.ptr_wrapper(), 5);
}
|
Going to retag this as wg-traits; kind of the best wg- label right now, even though we don't really discuss this |
Input from T-lang Backlog Bonanza meeting from 2022-02-09: Can anyone write down a summary of the status of this feature? Should any of the checkboxes in the description be checked off now as done? Do new checkboxes need to be added? |
Changing WG-traits to T-types. We discussed this in today's types triage meeting and ultimately decided that there are types decisions to be made here, so the team label feels appropriate. We don't have any concrete plans for this right now though. |
Here's a summary of this issue as requested in this comment @pnkfelix. Disclaimer: I haven't been involved so this may not be exactly right. But I'm interested in taking it forward so this summary was useful to compile anyway. What works now
Other work done
ConcernsThis attempts to be a complete summary of all known concerns raised in the discussions (at least, those visible on github). Please shout if I've missed something!
Next stepsThis seems to decompose nicely into several sequential RFCs.
The only blocker to doing step 2 is if we decide that we might not want to rely on |
This is closely related to rust-lang/rfcs#3324. There it was decided that upcasting on raw pointers is safe. This means, at the very least, that the safety invariant for raw dyn pointers says that the vtable is correct. Therefore it would only make sense to also make method calls safe. This means unsafe code constructing invalid raw dyn pointers is currently on shaky grounds -- we likely want to permit some invalid values for intermediate local use, but it is not yet determined which ones. |
One thing that I want to make sure we know that we're deciding now, is that this will work "by default" with This effectively locks us in the future to the |
Tracking issue for
#![feature(arbitrary_self_types)]
.This needs an RFC before stabilization, and also requires the following issues to be handled:
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.This doesn't have an RFC, but we want to experiment on this without one.
See #27941.
The text was updated successfully, but these errors were encountered: