nandi/rustnimpublic Fork
⑂ 3ba74c0
Commits
⬇ Clone ▾
git clone https://git.rickub.com/nandi/rustnim.git
git clone ssh://git@rickub.com/nandi/rustnim.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

Accept an associated const, and a braced expression, as an array length

`[u8; { ObjectIdentifier::MAX_SIZE }]` is two things at once: a braced const
expression, which is how rustc's expanded output writes one, and a qualified
path naming an associated const. Both are folded now -- the const under the
flattened `Type_CONST` name the lowering already emits it as.

A lowercase qualifier is a module path rather than a type, and carries no name
of its own, so it is still dropped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandithebull committed 2026-09-19T10:24:54-07:00 Browse files
3ba74c0 parent: 4cebd9c
modified src/lower.rs +1 -1
@@ -53,7 +53,7 @@ enum OpaqueKey {
5353 Method(String, String),
5454 }
5555
56-fn ident(name: &str) -> String {
56+pub(crate) fn ident(name: &str) -> String {
5757 if NIM_KEYWORDS.contains(&name) || NIM_SHADOWED.contains(&name) {
5858 return format!("{name}_r");
5959 }
@@ -53,7 +53,7 @@ enum OpaqueKey {
53 Method(String, String),53 Method(String, String),
54 }54 }
55 55
56-fn ident(name: &str) -> String {56+pub(crate) fn ident(name: &str) -> String {
57 if NIM_KEYWORDS.contains(&name) || NIM_SHADOWED.contains(&name) {57 if NIM_KEYWORDS.contains(&name) || NIM_SHADOWED.contains(&name) {
58 return format!("{name}_r");58 return format!("{name}_r");
59 }59 }
modified src/ty.rs +18 -4
@@ -540,13 +540,27 @@ pub fn const_expr(e: &syn::Expr) -> Result<String, String> {
540540 Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(i), .. }) => Ok(i.base10_digits().to_string()),
541541 Expr::Paren(p) => Ok(format!("({})", const_expr(&p.expr)?)),
542542 Expr::Group(g) => const_expr(&g.expr),
543+ // A braced const expression -- `[u8; { T::MAX_SIZE }]`, which is how
544+ // rustc's expanded output writes one.
545+ Expr::Block(b) => match b.block.stmts.last() {
546+ Some(syn::Stmt::Expr(e, None)) => const_expr(e),
547+ _ => Err("empty block in an array length".into()),
548+ },
543549 Expr::Path(p) => {
544- let seg = p
545- .path
546- .segments
550+ let segs: Vec<String> =
551+ p.path.segments.iter().map(|s| s.ident.to_string()).collect();
552+ let last = segs
547553 .last()
548554 .ok_or_else(|| "empty path in an array length".to_string())?;
549- Ok(seg.ident.to_string())
555+ // `Type::CONST` is an associated const, which the lowering emits
556+ // under the flattened name `Type_CONST`. A lowercase qualifier is
557+ // a module path instead, and carries no name of its own.
558+ if let Some(q) = segs.iter().rev().nth(1) {
559+ if q.starts_with(char::is_uppercase) {
560+ return Ok(crate::lower::ident(&format!("{q}_{last}")));
561+ }
562+ }
563+ Ok(last.clone())
550564 }
551565 Expr::Binary(b) => {
552566 let op = match b.op {
@@ -540,13 +540,27 @@ pub fn const_expr(e: &syn::Expr) -> Result<String, String> {
540 Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(i), .. }) => Ok(i.base10_digits().to_string()),540 Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(i), .. }) => Ok(i.base10_digits().to_string()),
541 Expr::Paren(p) => Ok(format!("({})", const_expr(&p.expr)?)),541 Expr::Paren(p) => Ok(format!("({})", const_expr(&p.expr)?)),
542 Expr::Group(g) => const_expr(&g.expr),542 Expr::Group(g) => const_expr(&g.expr),
543+ // A braced const expression -- `[u8; { T::MAX_SIZE }]`, which is how
544+ // rustc's expanded output writes one.
545+ Expr::Block(b) => match b.block.stmts.last() {
546+ Some(syn::Stmt::Expr(e, None)) => const_expr(e),
547+ _ => Err("empty block in an array length".into()),
548+ },
543 Expr::Path(p) => {549 Expr::Path(p) => {
544- let seg = p550+ let segs: Vec<String> =
545- .path551+ p.path.segments.iter().map(|s| s.ident.to_string()).collect();
546- .segments552+ let last = segs
547 .last()553 .last()
548 .ok_or_else(|| "empty path in an array length".to_string())?;554 .ok_or_else(|| "empty path in an array length".to_string())?;
549- Ok(seg.ident.to_string())555+ // `Type::CONST` is an associated const, which the lowering emits
556+ // under the flattened name `Type_CONST`. A lowercase qualifier is
557+ // a module path instead, and carries no name of its own.
558+ if let Some(q) = segs.iter().rev().nth(1) {
559+ if q.starts_with(char::is_uppercase) {
560+ return Ok(crate::lower::ident(&format!("{q}_{last}")));
561+ }
562+ }
563+ Ok(last.clone())
550 }564 }
551 Expr::Binary(b) => {565 Expr::Binary(b) => {
552 let op = match b.op {566 let op = match b.op {
modified tests/cases/052-const-array-len.rs +11 -0
@@ -4,6 +4,12 @@
44 const BLOCK: usize = 4;
55 const DOUBLE: usize = BLOCK * 2;
66
7+struct Oid;
8+
9+impl Oid {
10+ const MAX_SIZE: usize = 5;
11+}
12+
713 struct Buf {
814 data: [u8; BLOCK],
915 wide: [u8; DOUBLE],
@@ -34,4 +40,9 @@ fn main() {
3440 // get the answer from the same C ABI.
3541 let w: [u8; core::mem::size_of::<u32>()] = [5u8; core::mem::size_of::<u32>()];
3642 println!("{} {}", w.len(), sum(&w));
43+
44+ // An associated const as a length, and in the braces rustc's expanded
45+ // output writes it with.
46+ let q: [u8; { Oid::MAX_SIZE }] = [2u8; Oid::MAX_SIZE];
47+ println!("{} {}", q.len(), sum(&q));
3748 }
@@ -4,6 +4,12 @@
4 const BLOCK: usize = 4;4 const BLOCK: usize = 4;
5 const DOUBLE: usize = BLOCK * 2;5 const DOUBLE: usize = BLOCK * 2;
6 6
7+struct Oid;
8+
9+impl Oid {
10+ const MAX_SIZE: usize = 5;
11+}
12+
7 struct Buf {13 struct Buf {
8 data: [u8; BLOCK],14 data: [u8; BLOCK],
9 wide: [u8; DOUBLE],15 wide: [u8; DOUBLE],
@@ -34,4 +40,9 @@ fn main() {
34 // get the answer from the same C ABI.40 // get the answer from the same C ABI.
35 let w: [u8; core::mem::size_of::<u32>()] = [5u8; core::mem::size_of::<u32>()];41 let w: [u8; core::mem::size_of::<u32>()] = [5u8; core::mem::size_of::<u32>()];
36 println!("{} {}", w.len(), sum(&w));42 println!("{} {}", w.len(), sum(&w));
43+
44+ // An associated const as a length, and in the braces rustc's expanded
45+ // output writes it with.
46+ let q: [u8; { Oid::MAX_SIZE }] = [2u8; Oid::MAX_SIZE];
47+ println!("{} {}", q.len(), sum(&q));
37 }48 }