Builtin SymbolIds are a hard-coded list of 21 names; other std declarations are numbered per program
Limitation
SymbolTable::new pre-seeds exactly 21 std::core names at fixed ids: 18 types
(boolean, String, Char, the sized integers and floats, List, Perhaps,
Result, Range, RangeInclusive) and 3 aspects (Display, Iterable,
From). The list is Rust constants (SYM_TYPE_*, SYM_ASPECT_*) plus one
map.insert per name. The ranges 19-49, 53-99 and 100-999 are reserved "for
future stdlib types/aspects/expansion" and are unused. Every other std::core
declaration, for example Copy and Drop, is interned by the name resolver
like user code. intern_all_symbols sorts every declaration by (module path, name) before interning (metel-core#1129), so an id does not depend on the
order modules were loaded; but it is the declaration's rank in that sorted list,
so it shifts whenever a program adds or removes a declaration. Code that needs
these std items looks them up by (module, name) (coherence.rs does this for
Copy and Drop).
Impact
- Builtin identity has two sources of truth: the Rust table here and the
std::coremodule file (ADR-0039). Adding a std type that the runtime must register under a fixed id means editing both. - The ids of std declarations outside the 21 are stable for a given program whatever the load order, but they are ranks in that program's sorted declaration list, so they cannot be treated as well-known across programs.
- The reserved ranges document an intent that the code does not use.
None of this is observable from a Metel program. It is read from the code, so there is no reproducing fixture.
Affects
arch.name-resolution.requirement-1metel-frontend/src/identity/symbols.rs(SymbolTable::new, theSYM_*constants)
Resolution
None yet. Generating the fixed ids from the std::core declarations, or
dropping the fixed ids in favour of name lookup everywhere, would remove the
second source of truth.