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 upExtend Cell to non-Copy types #1651
Conversation
This comment has been minimized.
This comment has been minimized.
|
Oddly enough @SimonSapin, @nox, and I were just talking about this, and we ended up concluding that we probably wouldn't want to extend the I'd also personally err on the side of being conservative and drop |
sfackler
reviewed
Jun 15, 2016
| # Motivation | ||
| [motivation]: #motivation | ||
|
|
||
| It allows safe inner-mutability of non-`Copy` types without the overhead of `RefCell`'s reference counting. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
eefriedman
Jun 15, 2016
Contributor
https://github.com/SimonSapin/kuchiki/blob/23e92d45b7406865e035defdc5f5ca9f1809c406/src/tree.rs#L116 is the best example I could find with a quick search.
This comment has been minimized.
This comment has been minimized.
Can you explain this remark? As far as I can tell it's not true for PartialEq, so I want to know what assorted traits you refer to :) |
This comment has been minimized.
This comment has been minimized.
|
@durka ah yeah sure! So right now the standard library has: impl<T: PartialEq + Copy> PartialEq for Cell<T> { ... }If, however, impl<T: PartialEq> PartialEq for Cell<T> { ... }Unfortunately, though, we can't implement that. This means that we'd probably have to have |
This comment has been minimized.
This comment has been minimized.
|
Oh I see. I thought you were saying that it was On Wed, Jun 15, 2016 at 1:11 PM, Alex Crichton notifications@github.com
|
This comment has been minimized.
This comment has been minimized.
|
I actually formalised I have various use cases for both in Servo. https://github.com/nox/mitochondria/blob/master/src/move.rs#L3-L46 |
glaebhoerl
reviewed
Jun 15, 2016
| ```rust | ||
| impl<T> Cell<T> { | ||
| fn set(&mut self, val: T); | ||
| fn replace(&mut self, val: T) -> T; |
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.
|
Along with
we could also have
(the first two are symmetric with cc #1106 |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton You should be able to implement fn eq (&self, other: &Self) {
let self_ptr = self.as_unsafe_cell().get();
let other_ptr = other.as_unsafe_cell().get();
unsafe { &*self_ptr == &*other_ptr }
}Ah, wait, you could have some sort of way to access |
This comment has been minimized.
This comment has been minimized.
|
That is unsound because you call PartialEq from inside the UnsafeCell. |
kennytm
reviewed
Jun 16, 2016
| } | ||
| impl<T: Copy> Cell<T> { | ||
| fn get(&self); |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I think this needs to be in the detailed design:
pub fn set(&self, value: T) {
unsafe {
*self.value.get() = value;
}
}But for struct Evil(Box<u32>, Rc<MoveCell<Option<Evil>>>);
impl Drop for Evil {
fn drop(&mut self) {
mem::drop(self.1.take()); // Mess with the "other" node, which might be `self`.
self.0.clone(); // use after free!
}
}
let a = Rc::new(MoveCell::new(None));
a.replace(Some(Evil(Box::new(5), a.clone()))); // Make a reference cycle.
a.set(None); // Trigger Evil::drop while in the cellTo avoid this, the method needs to be rewritten so that pub fn set(&self, value: T) {
self.value.replace(value); // semi-colon to drop the return value of replace
} |
aturon
added
T-lang
T-libs
labels
Jun 21, 2016
aturon
self-assigned this
Jun 23, 2016
nox
referenced this pull request
Jun 28, 2016
Closed
Introduce a new type `MoveCell<T>` in `std::cell` #1659
This comment has been minimized.
This comment has been minimized.
|
@ubsan indeed, that is not sound, as the whole point of |
This comment has been minimized.
This comment has been minimized.
|
I'm in favor of having something like (I'd also like |
This comment has been minimized.
This comment has been minimized.
|
@rfcbot fcp close My personal preference would be to not enhance The second drawback mentioned is a showstopper for me. In general if you're working with a I'm going to propose that the libs team closes this RFC as a result of that drawback, but I'm curious to hear others' thoughts! |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Oct 10, 2016
•
|
Team member @alexcrichton has proposed to close this. The next step is review by the rest of the tagged teams: Concerns:
Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
This comment has been minimized.
This comment has been minimized.
|
Hmm. I am sad, because I think that having a plethora of |
This comment has been minimized.
This comment has been minimized.
|
I don't see why the There's no principle saying that every method/impl of a type should require the same trait bounds. I don't even understand why you would expect that. |
This comment has been minimized.
This comment has been minimized.
|
For me at least it's all about the surprise factor of using |
This comment has been minimized.
This comment has been minimized.
I agree with you on the general principle; but of course one has to evaluate each case on its merits. In this case particular case I feel conflicted. You're making me rethink my opinion a bit. Let me just throw out some various chaotic thoughts. Combining sharing and mutability is still a weak spotI feel like in general we need to smooth out our story on sharing + mutability. This begins with education: explaining better when it is legal to mutate (the naming of But also just looking at the APIs: The cell vs ref-cell split is logical, but not ideal. I think it's not well-explained, for one thing, but also it is often stricter than normal. Many uses of Moreover, and most importantly I think, I'd prefer if we had a widely usable alternative that avoided these pitfalls, so that we could promote it as the preferred way to have sharing and mutability (something like "avoid it if you can, but if not, use Note that there is nothing stopping me from prototyping these ideas in a crates.io crate except for laziness. =) What I would prefer: an expanded CellI would prefer if we could expand on Since we want to eliminate cell-related panics, we can't permit open-ended borrows like
The last few might seem surprising. The idea here is that we know that Note that I said Why partial eq bothers meOK, without that context, why do I care about Random middle groundI wonder if it'd be a good first step to just extend An irrelevant, whiny aside: why I wish cell did not have
|
This comment has been minimized.
This comment has been minimized.
I feel like there's a conceptual difference here between (Note that I'm not arguing against potentially adding the others as well at some point. Just against lumping them in with
I feel like the rationale here is much more straightforward than that: "Hey how come there isn't a "Try implementing it and find out." "Oh, I see. It seems like you can't express it using the API."
I agree with this completely and the same thought has occurred to me as well. (Another reference point is Haskell where |
This comment has been minimized.
This comment has been minimized.
|
Yep, good point. |
This comment has been minimized.
This comment has been minimized.
antrik
commented
Nov 16, 2016
|
Regarding mental model / documentation ergonomics, I believe this will actually improve the situation: I was recently thinking about how to best explain I'm surprised that some people are so vehemently contesting the usefulness of this. (On the now-closed The specific use case that brought me here is for Unix file descriptors, which I want to wrap in a non-copy type. (While technically they are just a This is an interesting example I think, because it demonstrates that the difference between a low-cost abstraction and a zero-cost abstraction can be fundamental: if we could continue using |
This comment has been minimized.
This comment has been minimized.
|
Apologies for the long delay moving forward on this! Given the thrust of the overall discussion here, it seems both that there's a pretty decent motivation, and a reasonable mental model. @Amanieu, can you update the RFC to try to incorporate some of the discussion, in particular around the motivation and mental model issues? (No changes needed to the actual design.) Meanwhile, I'll kick off the process for heading toward FCP. @rfcbot fcp merge |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Dec 21, 2016
•
|
Team member @aturon has proposed to merge this. The next step is review by the rest of the tagged teams:
No concerns currently listed. Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
This comment has been minimized.
This comment has been minimized.
|
@rfcbot reviewed |
This comment has been minimized.
This comment has been minimized.
|
ping @BurntSushi, @brson, @sfackler, @withoutboats please review! |
This comment has been minimized.
This comment has been minimized.
|
ping @withoutboats, only review left |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Jan 15, 2017
|
|
rfcbot
added
the
final-comment-period
label
Jan 15, 2017
aturon
referenced this pull request
Jan 23, 2017
Closed
Tracking issue for RFC 1651: Extend Cell to non-Copy types #39264
aturon
merged commit 3e925a5
into
rust-lang:master
Jan 23, 2017
This comment has been minimized.
This comment has been minimized.
|
The FCP period has elapsed without any further discussion, so the RFC has now been merged! Thanks @Amanieu! |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Jan 25, 2017
|
The final comment period is now complete. |
pitdicker
referenced this pull request
Jan 25, 2017
Merged
Extend Cell to work with non-Copy types #39287
This comment has been minimized.
This comment has been minimized.
|
Not sure if this is the right place to ask, but I have a question concerning this RFC: Why is |
This comment has been minimized.
This comment has been minimized.
|
Yeah, it seems sound to do that, it's probably still restricted because nobody thought of it. Might be worth opening up a quick rfc for this, or perhaps just bringing it up on the tracking issue. |
This comment has been minimized.
This comment has been minimized.
|
@RalfJung sounds good to me! (there's probably a few more methods that can be generalized as well) |
This comment has been minimized.
This comment has been minimized.
|
Also I don't think such a change would require an RFC any more |
This comment has been minimized.
This comment has been minimized.
|
Agreed, a PR is fine. |
This comment has been minimized.
This comment has been minimized.
|
All right, will prepare one. @alexcrichton well, the other two are taking a shared borrow of the Cell, so they are way more complicated to talk about. On the other hand, they are returning |
This comment has been minimized.
This comment has been minimized.
|
I think that only |
SimonSapin
referenced this pull request
Apr 10, 2017
Merged
proc_macro: implement `TokenTree`, `TokenKind`, hygienic `quote!`, and other API #40939
This comment has been minimized.
This comment has been minimized.
|
I did a comparison of the methods of
The main questions on top of my mind are:
It is totally fine to me if As niko stated above, the mental model of "Cell supports moving bits around, but never gives a reference to the inside" seems pretty coherent, before this RFC is merged. But after this RFC is merged, the distinction between these two types are very vague, and the motivation of this separation seems not strong enough. To make cell types as easy as it can be, I'm proposing to merge the methods together and make these two types exactly identical. We can update the mental model to: if you want to move bits around, use |
This comment has been minimized.
This comment has been minimized.
|
@F001 yes, it is necessary to have two, the inner implementation differs and the guarantees provided are different. |
This comment has been minimized.
This comment has been minimized.
|
@F001 To expand a bit on Manish’s explanation: an important invariant of safe Rust is that mutation cannot happen while there multiple ways (aliasing) to access something. This leads to the separation of
This tradeoff is why they both exist. And the different constraints explain the different API. Except for |
This comment has been minimized.
This comment has been minimized.
|
@SimonSapin I see. Thank you all for clarification. |
This comment has been minimized.
This comment has been minimized.
|
|
Amanieu commentedJun 15, 2016
This RFC extends the
Celltype to work with non-Copytypes.Rendered