fix: resolve qualified-import-member const as a compile-time constant (issue 0192)

A namespaced import's const (`m :: #import "lib.sx"; … m.CAP`) only ever
resolved as a runtime value — the const folders in program_index.zig had no
namespace-member arm, so a qualified const was rejected as an array dimension /
Vector lane / generic value-param and could not seed another const, while the
flat-import form worked everywhere.

Add a `lookupQualifiedConst` (+ float / float-typed twins) ctx hook: resolve
the alias via `namespaceAliasVerdictFrom` to its target module, then fold the
member from that module's per-source const cache (`foldQualifiedConstInt` in
lower/comptime.zig), pinned to the target source so nested const RHSs fold
there. Wire it into evalConstIntExpr / evalConstFloatExpr / isFloatValuedExpr —
both the expression-position field_access arm (`[m.CAP]T`) and the
type-argument dotted-name arm (`Vector(m.LANES, …)`, generic value-params).

Implemented on the source-aware ctxs (Lowering / SourceConstCtx); the
namespace-blind ModuleConstCtx / StatelessInner return null, so a qualified-const
dim reached only via the stateless type-alias path stays a clean unresolved-dim
diagnostic, never a fabricated length. Resolves correctly for array dims,
arithmetic, integral-float dims, Vector lanes, generic value-params, inline-for
bounds, and struct fields.

Regression: examples/modules/0842-modules-qualified-import-const-comptime.sx.
This commit is contained in:
agra
2026-06-26 07:51:27 +03:00
parent 6b8bce1aba
commit 501399b1a9
12 changed files with 361 additions and 6 deletions

View File

@@ -119,6 +119,15 @@ pub const SourceConstCtx = struct {
pub fn lookupConstStructField(self: SourceConstCtx, name: []const u8, field: []const u8) ?i64 {
return self.lowering.foldConstStructField(name, field, self.frame);
}
pub fn lookupQualifiedConst(self: SourceConstCtx, ns: []const u8, field: []const u8) ?i64 {
return self.lowering.foldQualifiedConstInt(ns, field, self.frame);
}
pub fn lookupQualifiedConstFloat(self: SourceConstCtx, ns: []const u8, field: []const u8) ?f64 {
return self.lowering.foldQualifiedConstFloat(ns, field, self.frame);
}
pub fn qualifiedNameIsFloatTyped(self: SourceConstCtx, ns: []const u8, field: []const u8) bool {
return self.lowering.qualifiedConstIsFloatTyped(ns, field, self.frame);
}
};
// ── Scope ───────────────────────────────────────────────────────────────
@@ -884,6 +893,18 @@ pub const Lowering = struct {
pub fn lookupConstStructField(self: *Lowering, name: []const u8, field: []const u8) ?i64 {
return self.foldConstStructField(name, field, null);
}
/// Qualified-import-member const leaf (`m.CAP`, issue 0192) for the shared
/// dimension evaluator — resolves the namespace alias `ns` to its target
/// module and folds its `field` const there.
pub fn lookupQualifiedConst(self: *Lowering, ns: []const u8, field: []const u8) ?i64 {
return self.foldQualifiedConstInt(ns, field, null);
}
pub fn lookupQualifiedConstFloat(self: *Lowering, ns: []const u8, field: []const u8) ?f64 {
return self.foldQualifiedConstFloat(ns, field, null);
}
pub fn qualifiedNameIsFloatTyped(self: *Lowering, ns: []const u8, field: []const u8) bool {
return self.qualifiedConstIsFloatTyped(ns, field, null);
}
/// Resolve a type node, checking type_bindings first for generic type params.
pub fn resolveTypeWithBindings(self: *Lowering, node: *const Node) TypeId {
@@ -1752,6 +1773,10 @@ pub const Lowering = struct {
pub const foldSourceConstInt = lower_comptime.foldSourceConstInt;
pub const foldSourceConstFloat = lower_comptime.foldSourceConstFloat;
pub const sourceConstIsFloatTyped = lower_comptime.sourceConstIsFloatTyped;
pub const selectQualifiedConst = lower_comptime.selectQualifiedConst;
pub const foldQualifiedConstInt = lower_comptime.foldQualifiedConstInt;
pub const foldQualifiedConstFloat = lower_comptime.foldQualifiedConstFloat;
pub const qualifiedConstIsFloatTyped = lower_comptime.qualifiedConstIsFloatTyped;
pub const comptimeIntNamed = lower_comptime.comptimeIntNamed;
pub const selectModuleConst = lower_comptime.selectModuleConst;
pub const GlobalAuthor = lower_comptime.GlobalAuthor;