A const generic argument mangles as its Debug-printed AST, spans and all
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 14
- Forks
- 2
- Avg merge
- 12h 42m
- Merged PRs (30d)
- 61
Description
Found while making the frontend runner execute its CHECK lines (#407). tests/frontend/pass/const_generics_types.vx emits:
func.func @threshold$const$Number_NumberExpr___value___3_14___ty__None__span__Span___line__0__column__0__length__0_____
Type::Const mangles by Debug-formatting the expression and replacing every non-alphanumeric character (syntax/types.rs):
Type::Const(expr) => {
let debug_str = format!("{:?}", expr);
let sanitized: String = debug_str.chars()
.map(|c| if c.is_alphanumeric() { c } else { '_' }).collect();
write!(w, "const${}", sanitized)
}
So a monomorph's identity is the syntax of its argument, not the value:
- The span is part of the name. It reads as zeros here, but wherever spans are populated the same constant written at two source positions becomes two distinct symbols, and one monomorph is emitted per call site.
- Two spellings of one value (
3and1 + 2, or3.14and3.140) are different names, so they monomorphize separately instead of sharing. - The name carries the whole AST node, so it grows without bound with the expression.
Same family as hiraditya/Vx.1#401, which fixed the tensor half of this: a symbol name has to distinguish exactly what varies the generated code. A const generic's value is what varies it; the expression that produced the value does not.
The fix is to mangle the evaluated constant — threshold$const$3_14 — which the checker can already compute (eval_expr folds these for the capacity and matmul checks). Where a const argument cannot be evaluated, that is worth refusing rather than naming by syntax.
The symptom that led here: the CHECK line pinning that function had to be written func.func @threshold_{{.*}}() -> f32, because no one could write the real name down.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in syntax/types.rs at Type::Const and inspect the checker’s eval_expr path used for capacity and matmul checks. Run tests/frontend/pass/const_generics_types.vx and examine the CHECK line for the threshold symbol. Done means equivalent constant values share a value-based mangled name, unevaluable const arguments are refused, and the test can pin the resulting symbol.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100