This is a tracking issue for the box_syntax feature, the special syntax for creating boxes, e.g. box 1usize
(note: box patterns is separate and is tracked at at https://github.com/rust-lang/rust/issues/29641)
This was previously under the same tracking issues as placement (#22181/#27779) but I didn't want to remove it (yet) due to widespread usage in the compiler (Box::new
is implemented in terms of it) and in the wider ecosystem (unlike <-
etc which only had a handful of crates using it).
Things to decide:
box
syntax be phased out?Box::new
is inline always, or does that not work?Note: when removing this, be careful not to remove the syntax entirely in order to not cause another case of https://github.com/rust-lang/rust/issues/50832
Do I understand it correctly that the box
syntax is dependent on placement-new (which has now been unapproved as an RFC)?
Personally I like the idea of having some syntactic sugar for creating something as common as a box (it does look nice). But obviously it would need to be built on something that works.
@spacekookie yes, the big deal for box syntax is placement new.
s there any reason for users to use box syntax (apart from it looking nice) given Box::new is inline always, or does that not work?
It doesn't optimize well, and even if it did, you would need some other way around it to avoid blowing up the stack in debug mode.
https://github.com/rust-lang/rust/issues/41160
is there any reason for users to use box syntax (apart from it looking nice) given Box::new is inline always, or does that not work?
So this is perhaps a bit of a weird usecase, but it is the only reason I have used box
at all: I do a lot of no_std
projects where the stack doesn't grow automatically. In these cases, using Box::new(MyLargeStruct)
will overrun the limited amount of stack space by allocating MyLargeStruct
on the stack and copying it to the allocated space. Allocating and initializing in place is critical.
The obvious alternative is to use the allocator directly and unsafely construct a Box from it, but that's annoying and ugly.
See example here: https://github.com/mark-i-m/os2/blob/2ab9d589a4463bd3133157b5c1a2f9f6735a3432/kernel/process/sched.rs#L76-L83
In most cases people just want to simplify the Box::new
s everywhere. I really want a shorter version and box
syntax sounds like a great idea.
Is there a recent plan of stabilizing box
syntax?
I think that there really isn't a convenient alternative for destructuring boxes without adding a lot of extra nesting. Personally, in very box
-heavy code I would prefer that box
destructuring be stabilized separately from box
placement syntax. For instance, in this file I have 14 uses of the box
destructuring syntax and only 1 of the box
placement syntax. The code would become significantly less readable from the removal of box
destructuring, whereas converting box <thing>
with Box::new(thing)
certainly doesn't bother me at all because the code is just as readable.
My thought then is that we should separate the tracking issue out for box
destructuring so we can get that stabilized. The only reason we might not want to do this is if we want to create a general RFC for pattern matching items into Deref
/DerefMut
as described here. I don't intend to create said RFC at this time, but if someone else wants to do that then I think that is a viable alternative.
This could possible alleviate my usecase: https://crates.io/crates/copyless
@vadixidav box destructuring(/patterns) is already tracked at https://github.com/rust-lang/rust/issues/29641 (see mention of 'box patterns' in the issue description)
I was looking at Box::pin
when I noticed, that box_syntax
is using the prefix syntax. But for the very reason (box x).into()
is ugly to type and chain, the await
operator(?) is using postfix syntax, So, maybe, for the same reasons, box
should use postfix syntax as well?
(box x).into()
vs
x.box.into()
At least, that is what came to my mind. Sorry if this is the wrong ticket or off topic, I just want to see rust getting continuously better and better :smiley:
x.box.into()
At least, that is what came to my mind. Sorry if this is the wrong ticket or off topic, I just want to see rust getting continuously better and better 馃槂
You could easily make a trait that adds a method and call it into_box
or boxed
:
x.boxed().into()
Implemented like:
trait Boxed {
fn boxed(self) -> Box<Self>;
}
impl<T> Boxed for T {
fn boxed(self) -> Box<Self> {
Box::new(self)
}
}
(adding type restrictions as needed)
For my use case, I'm less concerned with syntactic sugar (Box::new
is fine) but with blowing up the stack (in both debug and release mode) as @oyvindln and @mark-i-m suggested.
If I have a struct like:
const SIZE: usize = 4096*4096;
#[derive(Copy, Clone)]
#[repr(C, align(4096))]
pub struct Pages([u8; SIZE]);
impl Default for Pages {
fn default() -> Self {
Pages([0u8; SIZE])
}
}
Creating a Box<Pages>
without overflowing the stack is quite hard. Consider the following example implementations:
pub fn with_new() -> Box<Pages> {
Box::new(Pages([0u8; SIZE]))
}
pub fn with_box_syntax() -> Box<Pages> {
box Pages([0u8; SIZE])
}
pub fn with_default() -> Box<Pages> {
Default::default()
}
pub fn with_raw_alloc() -> Box<Pages> {
use std::alloc::{alloc_zeroed, Layout, handle_alloc_error};
let layout = Layout::new::<Pages>();
let ptr = unsafe { alloc_zeroed(layout) };
if ptr.is_null() {
handle_alloc_error(layout);
}
unsafe { Box::from_raw(ptr as *mut Pages) }
}
with_new
blows the stack in debug
and release
, while with_box_syntax
and with_default
blow the stack only in debug
mode. Godbolt Link
So even something like @mark-i-m's example isn't guaranteed to work. Should the box
syntax in with_box_syntax
be guaranteed to not blow the stack (even in debug
mode)?
Most helpful comment
In most cases people just want to simplify the
Box::new
s everywhere. I really want a shorter version andbox
syntax sounds like a great idea.Is there a recent plan of stabilizing
box
syntax?