Skip to content
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

User-defined placement-box #18233

Closed

Conversation

pnkfelix
Copy link
Member

Add support for user-defined placement-box expressions (i.e. box (<place>) <value> for types other than Box<T>).

This is a prototype design that @nikomatsakis and @pnkfelix have been working on. It works by desugaring an instance of placement-box into a protocol where we first create the intermediate storage with a pseudo-out-pointer, then initialize the storage, and then convert the out-pointer into the desired box type.

The code was originally written to handle both box (<place>) <value> and box <value> via the same uniform desugaring, and it is easy to revise support for the latter; but as is, this PR only puts box (<place>) <value> into the desugaring. The reason for this is that the error messages get a lot nastier to handle from the desugared form, and pnkfelix did not want to hold this work up further trying to resolve that.

The final design for this will require an RFC; this code is entirely experimental for now.

Proto RFC: http://discuss.rust-lang.org/t/pre-rfc-placement-box-with-placer-trait/729/5

Note that this narrows desugaring to only be when actual placer is
provided; `box <value_expr>` and `box () <value_expr>` both still fall
through to the `mk_unary(UnUniq, _)` path.

Many more compile-fail tests would need updating if we were not
restricting desugaring to `box` with explicit placer.
@rust-highfive
Copy link
Collaborator

warning Warning warning

  • These commits modify unsafe code. Please review it carefully!

@pnkfelix
Copy link
Member Author

r? @nikomatsakis

@pnkfelix
Copy link
Member Author

agh failed make tidy ... will fix pronto.

(okay, fixed now; earlier review request still stands. :)

@pnkfelix
Copy link
Member Author

(on reflection, I'm not sure why I thought printing from drop would be any better than failing from drop. I will revise those to just call fail as well.)

ExchangeHeapSingleton { _force_singleton: () };

/// This the singleton type used solely for `boxed::HEAP`.
pub struct ExchangeHeapSingleton { _force_singleton: () }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The term exchange heap really shouldn't be used. It's not how dynamic allocation works in Rust. It's wrong to refer to this as HEAP at all. The Box<T> type represents a dynamic allocation from the same allocator as other types like Vec<T> and Rc<T>. Rust doesn't draw any distinction between memory on a "heap" and other memory mappings.

@thestinger
Copy link
Contributor

The box placement protocol should be designed with the same flexibility as placement new / perfect forwarding in C++. It should be possible to push onto a vector by building the element in-place rather than constructing it and copying it inside. I don't think these concerns are being addressed by the design effort put into box, so I'm against progressing with it further.

@thestinger
Copy link
Contributor

There needs to be a clear plan on how this is going to work for use cases like vector or hash table inserts before I'm comfortable with it, because I don't want to see Rust end up with an inadequate language feature that needs to be duplicated.

@nikomatsakis
Copy link
Contributor

@thestinger Good point, that is an important use case. I don't see any trouble expressing something like emplace_back. (In fact, @pnkfelix just pushed a commit showing how it can be done: b293984). What do you think? In any case, as @pnkfelix said, we plan to write an RFC, so it'd be great to get a good list of any other requirements you have in mind so that we can write up how the design handles them.

@thestinger
Copy link
Contributor

If it can support emplace_back then I think it's flexible enough to cover most use cases of perfect forwarding / placement new in C++. I can't think of another major use case for it at the moment.

This made some things cleaner (e.g. I got to get rid of the `Cell` in
the `AtomPool` example). But it also highlights some weaknesses in my
current expansion -- namely, my use of top-level functions rather than
methods means that I am currently forced to make sure I have the right
level of borrowing in the PLACER input in `box (PLACER) EXPR`. I will
look into my options there -- it may be that the right thing is just
to switch to method invocations.
/// the fact that the `align_of` intrinsic currently requires the
/// input type to be Sized (which I do not think is strictly
/// necessary).
pub struct IntermediateBox<Sized? T>{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is public, we'll be committing to the continued existence of this type, at least. I'm ok with this but cc @aturon. We'll probably want to bikeshed the name :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Of course there's no way to avoid having this be public, at least not without private trait methods at the very least...)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In particular I expect we want to reuse the "agent" term

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Thu, Nov 06, 2014 at 07:48:41AM -0800, Felix S Klock II wrote:

(Of course there's no way to avoid having this be public, at least not without private trait methods at the very least...)

Yes. And I think that's ok.

// implement the Placer trait. Likewise, the actual
// expansion below actually calls free functions in
// `std::ops::placer`, in order to avoid the need for UFCS
// (and also to hopefully produce better error messags).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think just using Placer::place(&mut <place_expr>) and so on will have a similar effect

@nikomatsakis
Copy link
Contributor

It probably makes sense to leave these for follow-up PRs, but it'd be nice to have placer implementations for:

  1. Rc
  2. Arc
  3. &TypedArena (as discussed)
  4. emplace_back, perhaps something with hashtable insert, etc

We should perhaps make a tracker issue (after this lands) for those sorts of things. Not a huge deal as they can be added as we like.

@pnkfelix
Copy link
Member Author

pnkfelix commented Nov 6, 2014

(added link to Proto RFC on discuss to the description; you can see it here: http://discuss.rust-lang.org/t/pre-rfc-placement-box-with-placer-trait/729/5 )

@steveklabnik
Copy link
Member

This needs a rebase.

@pnkfelix
Copy link
Member Author

(closing; I no longer think this is on the 1.0 timeframe)

@pnkfelix pnkfelix closed this Dec 16, 2014
@pnkfelix
Copy link
Member Author

see #22086

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants