Why do const generics need "Braces" when the path of a constant is composed of "::"?

Hello,

I recently tried to structure constant values in a module for use in a const generic, but it didn't work.

  • CONST_A // WORK
  • id_sequence::CONST_B // NOT WORK
  • { id_sequence::CONST_B } // WORK

I don't understand why.

When id_sequence::CONST_B surround it with braces { } it works, (what is the reason for this choice of syntax?)

Playground CODE

pub mod id_sequence {
    pub const CONST_B: u32 = 1;
}

pub const CONST_A: u32 = 1;


pub struct AutoIncrementID<const S: u32>(Option<i64>);


pub fn main() {
    let work: AutoIncrementID<CONST_A> = AutoIncrementID(None);
    
  
    let work_too: AutoIncrementID< { id_sequence::CONST_B }> = AutoIncrementID(None);
    
    
    // why ?
    let not_work: AutoIncrementID<id_sequence::CONST_B> = AutoIncrementID(None);

}

maybe there's a good reason for using { }, but I can't see the need in this case.

Thank you in advance for enlightening me on this question

Not sure, but the design document for the generic const expressions feature might be a good start to look into the syntactic reasons for this: Const well-formedness and const equality - HackMD

2 Likes

RFC 2000:

When applying an expression as const parameter (except for arrays), which is not an identity expression, the expression must be contained within a block. This syntactic restriction is necessary to avoid requiring infinite lookahead when parsing an expression inside of a type.

It also avoids some ambiguities.

const X: usize = 10;
some::path::<X>12>();
some::path::<{ X > 12}>();

It can also be used to disambiguate a const from a type (which have different namespaces).

6 Likes

id_sequence::CONST_B is it considered an expression? (it's just a "path" for me)

it replaces a :

use crate::id_sequence::* ;

    let v: AutoIncrementID< { CONST_B }> = AutoIncrementID(None);

it's not an expression that needs to be calculated :thinking:

This portion of the reference is a little more nuanced, perhaps.[1] Note the cavaet:

Const arguments must be surrounded by braces unless they are a literal or a single segment path.

(But I'm not really interested in arguing semantics myself.)


  1. Note that as far as I know, there is not an actual complete, normative grammar specification. ↩ī¸Ž

1 Like

Thank you very much, that's the answer I was looking for. :pray:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.