onlinepersona, (edited )

I’m not getting it. What’s the point? It seems very much like a cpp-ism where you can put const in so many places.


<span style="font-weight:bold;color:#a71d5d;">const int</span><span style="color:#323232;"> n2 </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#0086b3;">0</span><span style="color:#323232;">;    </span><span style="font-style:italic;color:#969896;">// const object
</span><span style="font-weight:bold;color:#a71d5d;">int const</span><span style="color:#323232;"> n3 </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#0086b3;">0</span><span style="color:#323232;">;    </span><span style="font-style:italic;color:#969896;">// const object (same as n2)
</span><span style="font-style:italic;color:#969896;">// https://learn.microsoft.com/en-us/cpp/cpp/const-and-volatile-pointers?view=msvc-170
</span><span style="font-weight:bold;color:#a71d5d;">const char *</span><span style="color:#323232;">cpch;  </span><span style="font-style:italic;color:#969896;">// const variable cannot point to another pointer
</span><span style="font-weight:bold;color:#a71d5d;">char * const</span><span style="color:#323232;"> pchc; </span><span style="font-style:italic;color:#969896;">// value of pointer is constant
</span><span style="color:#323232;">
</span><span style="font-weight:bold;color:#a71d5d;">int </span><span style="font-weight:bold;color:#795da3;">f</span><span style="color:#323232;">() </span><span style="font-weight:bold;color:#a71d5d;">const</span><span style="color:#323232;">; </span><span style="font-style:italic;color:#969896;">// members cannot be modified in this, only read
</span><span style="color:#323232;">std::string </span><span style="font-weight:bold;color:#a71d5d;">const </span><span style="font-weight:bold;color:#795da3;">f</span><span style="color:#323232;">(); </span><span style="font-style:italic;color:#969896;">// returns a constant
</span>

Then there are constant expressions.

Can anybody look at that and tell me it’s readable with a straight face? I hope they don’t start adding all this stuff to rust.

Anti Commercial-AI license

Miaou,

It can be used for producing const values in arbitrary context. Can basically be swapped for c++'s constexpr.

C++'s const does not exist in rust (values are const by default).

fzz,
@fzz@programming.dev avatar

Nope. This little neat feature mainly is just necessary part of bigger one - const-generics with const bounds.

sugar_in_your_tea,

Huh, this is awesome! From the link, this now works:


<span style="color:#323232;">let v: Vec<i32> = const { Vec::new() };
</span>

I’m going to have to play with this to see how far it goes.

jasory,

Wouldn’t this just prevent you from allocating more memory (than zero)?

sugar_in_your_tea, (edited )

Ah, apparently for now you’re not allowed to allocate. But vec::new_in(allocator) looks interesting. This works in nightly today:


<span style="color:#323232;">#![feature(allocator_api)]
</span><span style="color:#323232;">
</span><span style="color:#323232;">use std::alloc::Global;
</span><span style="color:#323232;">
</span><span style="color:#323232;">fn main() {
</span><span style="color:#323232;">    const MY_VEC: Vec<i32> = const {
</span><span style="color:#323232;">        Vec::new_in(Global)
</span><span style="color:#323232;">    };
</span><span style="color:#323232;">    println!("{:?}", MY_VEC);
</span><span style="color:#323232;">}
</span>

Maybe at some point I can append to it at compile time too. I’d love to be able to put a const {} and have allocations that resolve down to a 'static, and this seems to be a step toward that.

I guess I’m just excited that Vec::new() is the example they picked, since the next obvious question is, “can I push?”

kevincox,
@kevincox@lemmy.ml avatar

This is a nice small feature. I’m curious about the commit description:



<span style="color:#62a35c;">foo</span><span style="color:#323232;">(</span><span style="font-weight:bold;color:#a71d5d;">const </span><span style="color:#323232;">{ </span><span style="color:#0086b3;">1 </span><span style="font-weight:bold;color:#a71d5d;">+ </span><span style="color:#0086b3;">1 </span><span style="color:#323232;">})
</span>

which is roughly desugared into


<span style="font-weight:bold;color:#a71d5d;">struct </span><span style="color:#323232;">Foo;
</span><span style="font-weight:bold;color:#a71d5d;">impl </span><span style="color:#323232;">Foo {
</span><span style="color:#323232;">    </span><span style="font-weight:bold;color:#a71d5d;">const </span><span style="color:#0086b3;">FOO</span><span style="color:#323232;">: </span><span style="font-weight:bold;color:#a71d5d;">i32 = </span><span style="color:#0086b3;">1 </span><span style="font-weight:bold;color:#a71d5d;">+ </span><span style="color:#0086b3;">1</span><span style="color:#323232;">;
</span><span style="color:#323232;">}
</span><span style="color:#62a35c;">foo</span><span style="color:#323232;">(Foo::</span><span style="color:#0086b3;">FOO</span><span style="color:#323232;">)
</span>

I would have expected it to desugar to something like:


<span style="color:#62a35c;">foo</span><span style="color:#323232;">({
</span><span style="color:#323232;">  </span><span style="font-weight:bold;color:#a71d5d;">const </span><span style="color:#0086b3;">TMP</span><span style="color:#323232;">: </span><span style="font-weight:bold;color:#a71d5d;">i32 = </span><span style="color:#0086b3;">1 </span><span style="font-weight:bold;color:#a71d5d;">+ </span><span style="color:#0086b3;">1</span><span style="color:#323232;">;
</span><span style="color:#323232;">  </span><span style="color:#0086b3;">TMP
</span><span style="color:#323232;">})
</span>

But I can’t seem an explanation why the struct with impl is used. I wonder if it has something to do with propagating generics.

0v0,

It’s because it has to work in pattern contexts as well, which are not expressions.

SorteKanin,
@SorteKanin@feddit.dk avatar

Wait, in pattern context? How? Can you give an example?

0v0,

<span style="font-weight:bold;color:#a71d5d;">fn </span><span style="font-weight:bold;color:#795da3;">foo</span><span style="color:#323232;">(x: </span><span style="font-weight:bold;color:#a71d5d;">i32</span><span style="color:#323232;">) {
</span><span style="color:#323232;">    </span><span style="font-weight:bold;color:#a71d5d;">match</span><span style="color:#323232;"> x {
</span><span style="color:#323232;">        </span><span style="font-weight:bold;color:#a71d5d;">const </span><span style="color:#323232;">{ </span><span style="color:#0086b3;">3.</span><span style="color:#62a35c;">pow</span><span style="color:#323232;">(</span><span style="color:#0086b3;">3</span><span style="color:#323232;">) } </span><span style="font-weight:bold;color:#a71d5d;">=> </span><span style="color:#323232;">println!(</span><span style="color:#183691;">"three cubed"</span><span style="color:#323232;">),
</span><span style="color:#323232;">        </span><span style="font-weight:bold;color:#a71d5d;">_ => </span><span style="color:#323232;">{}
</span><span style="color:#323232;">    }
</span><span style="color:#323232;">}
</span>

But it looks like inline_const_pat is still unstable, only inline_const in expression position is now stabilized.

Giooschi,

They tested the same strings on that implementation

The code they were looking at was used for writing the table, but they were testing the one that read it (which is instead correct).

though judging by the recent comments someone’s found something.

Yeah that’s me :)The translation using an associated const also works when the const block uses generic parameters. For example:


<span style="color:#323232;">fn require_zst<T>() {
</span><span style="color:#323232;">    const { assert!(std::mem::size_of::<T>() == 0) }
</span><span style="color:#323232;">}
</span>

This can be written as:


<span style="color:#323232;">fn require_zst<T>() {
</span><span style="color:#323232;">    struct Foo<T>(PhantomData<T>);
</span><span style="color:#323232;">    impl<T> Foo<T> {
</span><span style="color:#323232;">        const FOO: () = assert!(std::mem::size_of::<T>() == 0);
</span><span style="color:#323232;">    }
</span><span style="color:#323232;">    Foo::<T>::FOO
</span><span style="color:#323232;">}
</span>

However it cannot be written as:


<span style="color:#323232;">fn require_zst<T>() {
</span><span style="color:#323232;">    const FOO: () = assert!(std::mem::size_of::<T>() == 0);
</span><span style="color:#323232;">    FOO
</span><span style="color:#323232;">}
</span>

Because const FOO: () is an item, thus it is only lexically scoped (i.e. visible) inside require_zst, but does not inherit its generics (thus it cannot use T).

  • All
  • Subscribed
  • Moderated
  • Favorites
  • rust@programming.dev
  • DreamBathrooms
  • everett
  • osvaldo12
  • magazineikmin
  • thenastyranch
  • rosin
  • normalnudes
  • Youngstown
  • Durango
  • slotface
  • ngwrru68w68
  • kavyap
  • mdbf
  • InstantRegret
  • JUstTest
  • ethstaker
  • GTA5RPClips
  • tacticalgear
  • Leos
  • anitta
  • modclub
  • khanakhh
  • cubers
  • cisconetworking
  • megavids
  • provamag3
  • tester
  • lostlight
  • All magazines