6

Github Add the boxed!() macro to "de-magic" box syntax by not-a-seagul...

 3 years ago
source link: https://github.com/rust-lang/rfcs/pull/3057
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

not-a-seagull commented 6 days ago

edited

Box syntax (e.g. box x) is controversial due to its "magic" status in the language. This RFC proposes the addition of a boxed macro that would remove the magic syntax from this feature (e.g. boxed!(x)).

Rendered

not-a-seagull

changed the title Adds the boxed!() macro to "de-magic" box syntax

Add the boxed!() macro to "de-magic" box syntax

6 days ago

Contributor

Havvy commented 6 days ago

Given that box is not stable, and neither would the macro you are proposing, this should be done as a Major Change Proposal.

As somebody who is not part of the compiler team though, the difference between unstable syntax and macros is basically zero, so this just looks like churn for the sake of churn.

Contributor

Lokathor commented 6 days ago

Doing this as an RFC so that it has a clear path to stability is fine, in terms of process.

However, I also don't see how this fixes much. box <expr> is entirely fine syntax, so we should just stabilize that if we eventually want a stable boxing syntax.

Member

mark-i-m commented 5 days ago

I would prefer to add magic syntax and remove it in a future edition than add a macro with a magic implementation and be stuck with it in the std library forever.

I do like the motivation of trying to hide some of the magic though.

Contributor

clarfonthey commented 4 days ago

Personally, I thought that the main reason why box wasn't stabilised wasn't because it was too magic of a syntax, but because we weren't sure how to generalise it in such a way that it would work generically for any kind of heap allocation, rather than just applying to box. And, there was the issue of box patterns, which I think has been resolved and they won't be needed anyway.

The thing I do like about using a boxed! macro instead of a box syntax that gets removed is that we already have this magic macro with vec!, and the precedent would be to add a box! macro like it. (I would call it box! instead of boxed! though, for consistency.) Ultimately, whatever generic solution is used should also work for Vec, and that would also make the vec! macro redundant as well.

@clarfonthey vec! macro isn't magic, it's just a normal macro. It does defer to some implementations that utilize specialization, but specialization that's no different from the rest of std. Funnily enough, vec! does utilize the box syntax internally. Again, utilizing unstable syntax/features within a macro is not a big deal. For an example of a magic macro, look no further than format_args eyes

Contributor

clarfonthey commented 4 days ago

Oh, I guess I should have clarified -- while vec! isn't strictly magic and mostly doesn't need anything like box to work, it's also essentially the same as Vec::from(box [...]).

nacaclanga commented 3 days ago

edited

Stabilizing boxed! or r#box! rather them the original box syntax has the advantage that vec::Vec and boxed::Box instances, can be created in very similar fashion, by calling a macro with the same name as the module, they are defined in (or the type name in lowcase in case of r#box!). In addition to not adding new syntax, boxed! or r#box!() can be defined in alloc, whereas the box syntax is awailable even when the boxed::Box type is not available at all. In case of r#box!, if we define it as a syntax extension like format_args!, we can remove the box syntax feature and the box keyword entierly. This would allow the macro to be called simply using box!.

The [`vec`](https://doc.rust-lang.org/src/alloc/macros.rs.html#37-47) macro is implemented in terms of it,

and several other parts of the [standard library](https://doc.rust-lang.org/src/alloc/sync.rs.html#314-318)

use it.

[`Box::new`](https://doc.rust-lang.org/std/boxed/struct.Box.html#method.new) is the stable alternative to this;

KodrAus 3 days ago

edited

Contributor

Can we think of any real-world examples that aren't already served by the vec! macro that are likely to be big enough to overflow the stack?

This function for example:

fn big_boxed_slice(init: u8) -> Box<[u8]> {
    Box::new([init; 10485760])
}

allocates a 10MiB array, and (currently) overflows in both debug and release mode.

The alternative with box expr (or boxed!) would be:

fn big_boxed_syntax_slice(init: u8) -> Box<[u8]> {
    boxed!([init; 10485760])
}

which doesn't overflow, but is equivalent to the already stable:

fn big_vec(init: u8) -> Box<[u8]> {
    vec![init; 10485760].into_boxed_slice()
}

Playground link

Contributor

KodrAus commented 3 days ago

I would prefer to add magic syntax and remove it in a future edition than add a macro with a magic implementation and be stuck with it in the std library forever.

I think I follow this train of thought that I don't think an intentionally temporary boxed! macro will really move us forwards, but if we did want to commit to a boxed! macro instead of the user-facing language feature to the point of linting against Box::new then I think that could be worth exploring. Once there is a stable way to avoid the stack blowup problem there's really no reason to ever consider the "broken" alternative, right?

Maybe this has come up before but have we ever thought about trying to make Box::new(expr) magically equivalent to the already magic box expr?

Member

kennytm commented 3 days ago

We do have #2884 for in-place construction at library level, at the cost of spec-guaranteed RVO.

// the closure's return is guaranteed to be written to box, 
// rather than written to stack then memcpy into the box
let mut hectapus = Box::with(|| Hectapus { arm_lengths: [0; 100] });

(I also think let x: Rc<T> = box T::new() is extremely confusing, since the Box type has already taken the name)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK