Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upTweaks to the object-safety rules #817
Conversation
nrc
assigned
nikomatsakis
Feb 9, 2015
solson
reviewed
Feb 9, 2015
| The reason that this makes sense is that if one were writing a generic | ||
| function with a type parameter `T` that may range over the trait | ||
| object, that type parameter would have to be declared `?Sized`, and | ||
| hence would not have access to the `bar` method: |
This comment has been minimized.
This comment has been minimized.
sfackler
reviewed
Feb 9, 2015
| * must not take `self` by value; and, | ||
| * must not use `Self` (in the future, where we allow arbitrary types | ||
| for the receiver, `Self` may only be used for the type of the | ||
| receiver and only where we allow `Sized?` types). |
This comment has been minimized.
This comment has been minimized.
sfackler
Feb 9, 2015
Member
Didn't we also add a restriction making static methods (like the new below) non-object safe?
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Feb 9, 2015
Author
Contributor
ah, yes. Though I don't think of it as "add" so much as "forget" the first time.
nikomatsakis
added some commits
Feb 9, 2015
This comment has been minimized.
This comment has been minimized.
|
Does this obsolete the need for an |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton I believe that is correct, yes. Ideally, though, we'd find a way for those methods to be usable on iterator objects as well! I guess the major problem is that they frequently take |
This comment has been minimized.
This comment has been minimized.
|
@aturon and I discussed this a little more today, and it looks like we won't actually want to remove the From what we talked about though, any consuming method no longer necessarily needs to live in an extension trait as they can all just be tagged with |
This comment has been minimized.
This comment has been minimized.
|
I’d rather like a built-in trait which is automatically implemented for all types except trait objects, allowing things like @alexcrichton On the topic of object safety rules, but slightly off-topic from the actual RFC, I’ve often wanted to tweak the ‘must not use |
This comment has been minimized.
This comment has been minimized.
|
I'm in favour. If we ever get type inequalities this would be "optimal" as |
nikomatsakis
added some commits
Feb 11, 2015
This comment has been minimized.
This comment has been minimized.
|
I just pushed a slight adjustment that permits by-value self methods as well. The reasoning is two-fold:
In particular, this allows us to define I also included some text highlighting that there is room to make the rules more liberal in the future. |
This comment has been minimized.
This comment has been minimized.
|
(Note also that the question of |
This comment has been minimized.
This comment has been minimized.
|
How exactly could by-value If we ever do allow unsized by-value |
This comment has been minimized.
This comment has been minimized.
theemathas
commented
Feb 12, 2015
|
What about type parameters or associated types that default to |
This comment has been minimized.
This comment has been minimized.
|
The key here is a realization we had a while back about fn cycle(self) -> Cycle<Self> where Self: CloneThis is a method that only needs to be implemented on The same principle is being applied here, with |
This comment has been minimized.
This comment has been minimized.
|
I was talking with @wycats and realized that the use of In particular, since Put differently, given the above, the only reason to have the object safety check is to force people to manually annotate with |
This comment has been minimized.
This comment has been minimized.
|
@aturon I understand the trait Foo {
fn foo(self);
}Trait impl Foo for Foo {
fn foo(self) { self.foo() } // error: the trait `core::marker::Sized` is not implemented for the type `Foo`
}So I don’t see how this could be considered object-safe. |
This comment has been minimized.
This comment has been minimized.
|
@P1start Ah, sorry! I think the point is that by-value self is interpreted as an implicit |
aturon
referenced this pull request
Feb 13, 2015
Closed
RFC: remove blanket ext implementations #502
This comment has been minimized.
This comment has been minimized.
|
@aturon interesting thought. One downside is that, as @huonw has pointed out, |
This comment has been minimized.
This comment has been minimized.
|
(I guess @huonw's suggestion of |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis Yes. @huonw and I chatted about this on IRC -- in my proposal, I don't literally mean interpreting as |
This comment has been minimized.
This comment has been minimized.
|
@aturon well, you have to be able to write it out, because we need to be able to use it as a bound on generic fns like |
This comment has been minimized.
This comment has been minimized.
|
(Or rather, we need them to not be callable if |
This comment has been minimized.
This comment has been minimized.
|
Basically I guess you can interpret the object safety rules as an additional way of ruling out that for |
This comment has been minimized.
This comment has been minimized.
So, to be clear, we'll want to eventually be able to write it out to take full advantage of the flexibility. But in the meantime, interpreting as something compiler-internal should be enough to (1) provide (But maybe I'm confused?) |
This comment has been minimized.
This comment has been minimized.
|
@aturon my point is that it cripples traits that do not need to be object safe. For example, if I wrote a trait trait MapToVec {
fn map_to_vec<U>(&self) -> Vec<U>;
}
impl<T> MapToVec for [T] { ... } and I wanted to use that trait: fn use_map_to_vec<T:MapToVec+?Sized>(t: &T) -> Vec<i32> {
t.map_to_vec::<i32>()
}The compiler would presumably have to disallow the call to That example is a bit odd in that I left out some type parameters and other things one would need to make it realistic, but doesn't seem especially far-fetched to me. |
This comment has been minimized.
This comment has been minimized.
|
I'd like to point out though that we can easily evolve object safety in the direction you propose, which I consider promising, though of course we won't be able to go back and fix traits in the meantime. |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis Thanks, I understand the worry better now. But yes, I'm a little worried about precisely what we'll freeze into e.g. |
This comment has been minimized.
This comment has been minimized.
|
The conservative path seems to be keeping While I find the idea that all traits are object-safe very appealing, it's not clear to me how much that change would give us forwards compatibility. In particular, if we allows fns that use banned features to assume that "Self is not a trait object" (and hence use methods with other banned features), then if we expand the set of things that are possible to do with objects -- e.g., I'd like to include by-value self -- we're in a certain amount of trouble, since existing impls might be relying on that guarantee. But if we make them right it out specifically in the form of a where clause, then the trait is still locked into not support object type receivers when it could. On the other hand, I don't see how we could ever support generic methods through virtual dispatch, at least without dynamic code generation or some additional list (on the trait) of pre-defined types. So that's a fairly safe case where you can assume that |
This comment has been minimized.
This comment has been minimized.
Strictly speaking, it's possible to be relying on I think going with |
This comment has been minimized.
This comment has been minimized.
|
@aturon agreed. I'd also really like to move forward with this RFC because it allows motion on fn trait inheritance. |
nikomatsakis
referenced this pull request
Feb 13, 2015
Merged
Allow methods that require `Self:Sized` to be object safe (RFC 817) #22301
This comment has been minimized.
This comment has been minimized.
|
Just FYI, impl is rust-lang/rust#22301 :) |
This comment has been minimized.
This comment has been minimized.
|
FWIW I'm happy to land this RFC for now and separately follow up on the more implicit design later. |
This comment has been minimized.
This comment has been minimized.
|
I was able to do some nice cleanup of parts of rust-postgres using @nikomatsakis's branch: sfackler/rust-postgres@aa4cad7. |
nikomatsakis
referenced this pull request
Feb 17, 2015
Merged
Tweak handling of `Self` in object-safety rules and type parameter defaults #22452
aturon
merged commit 74b05c6
into
rust-lang:master
Feb 18, 2015
This comment has been minimized.
This comment has been minimized.
|
This RFC makes it possible to have your cake and eat it too: we get |
nikomatsakis commentedFeb 9, 2015
Amend object safety RFC to include the complete set of rules, along with an exemption that permits individual methods to require that
Self:Sized.Implemented on the following branch:
https://github.com/nikomatsakis/rust/tree/object-safe-sized-methods