Compiler design / 08. Compile-time semantics
Folded constants, concrete generic requests, static trait evidence and explicit casts finish before HIR begins.
HIR and backends should not re-solve the same compile-time questions on every function body. Work that can finish early should finish early.
If a value never changes at runtime, fold it. If a generic call needs a concrete function, request one. If a trait bound needs evidence, resolve it. If a conversion needs a cast, emit an explicit operation.
AST owns that static work.
greeting_prefix begins as source:
greeting_prefix #= "Hello"
After checking and folding, it becomes a backend-neutral compile-time value. Exported folded facts copy into the immutable module interface. Consumers never re-parse or re-fold the provider's template or literal.
Constants are compile-time declarations and metadata, not runtime top-level statements. Const records may group fully folded struct or anonymous-record constants as field-access-only compile-time data. They are not runtime values to pass around.
Imported build values and resolved source #Import primitives enter as ordinary folded constants. They create no runtime wrapper type and no special HIR node category.
Diagram placeholder: Authored string becomes a backend-neutral compile-time value
Caption: exact semantic handoff, simplified storage. Question: what leaves the runtime program entirely?
A generic template lives in the declaring module as an immutable validated template. At a call site, AST:
The build system aggregates, deduplicates and schedules requests. The compiler materialises each accepted request as a generated sidecar beside the base module. Base artefacts stay immutable. Generated functions carry their own HIR, borrow facts and link facts. New concrete code grows beside the original template. The template itself does not mutate.
HIR and backends never infer generic arguments or consume unresolved template state. Concrete code appears before they look.
Diagram placeholder: One call creates a named request which later materialises beside the base module
Caption: accepted architecture. Question: when does generic code become concrete?
Traits and conformances are compile-time frontend metadata. AST validates requirements, explicit conformances, evidence visibility and bound-provided receiver calls.
Static bound calls resolve to concrete executable targets before HIR. HIR carries no trait objects, erased dispatch or runtime trait evidence.
That choice rejects a familiar dynamic path. You cannot box "any Show" and discover methods later. You can write choices for closed heterogeneity and generics with evidence for static reuse.
Diagram placeholder: A trait bound resolves before HIR
Caption: simplified static dispatch. Question: what replaces a trait object in this model?
Contextual coercion and explicit cast remain different paths.
Coercion happens when a receiving boundary accepts a value under documented rules. The boundary owner applies it.
Explicit cast is AST-owned conversion under compiler-defined policy and evidence. Foldable casts fold. Runtime casts become explicit operations. User-defined cast evidence becomes an ordinary direct function call before or during HIR lowering. Cast metadata itself does not tour HIR as a mini language.
Failures belong at the cast site or boundary with structured diagnostics, not as a quiet backend surprise.
Diagram placeholder: Contextual acceptance and explicit conversion take separate paths
Caption: teaching distinction. Question: who requested conversion?
Numbers look simple until every layer invents its own rules.
Accepted ownership splits cleanly:
numeric_text owns lexical grammar and materialisation helpersNumber and related roadmap work such as NumberN ideas may still be landing. Keep current Number and Byte status on the progress matrix separate from the ownership split above. The split is accepted even while surface coverage grows.
Do not re-teach diagnostic transport here. The semantic rejection is the point.
Alternative: dynamic trait objects, broad implicit conversion and runtime generic interpretation.
Choice: static evidence, compiler-owned casts and concrete requests.
Benefit: HIR and backends receive fewer open-ended semantic questions. Parallel targets share one answered story.
Cost: less runtime dynamism and more compile-time rejection when evidence is missing.
number_type_numeric_plan.md and import_values_anonymous_records_plan.md.You leave with folded constants, concrete requests, static evidence and finalised cast operations. Next: why the HTML template needs a temporary structural IR before HIR runtime work.