fix(gen): list iteration loads the real element type

`for v in list[T]` allocated the loop variable as i8* and loaded each
element through i8*, so integer elements were treated as pointers. A
later reuse of the same name, e.g.

    for i in nums:  ...          # i becomes i8*
    for i in range(6): ...       # stores/compares 6 in the i8* slot

then materialized a pointer-typed constant 6 and failed the renderer
with `[MLIR-FAIL] unsupported constant operand form (type '!llvm.ptr',
value '6')`.

Resolve the element type from the list specialization
(`_list_elem_type_from_name`: list[int] -> i32, list[str] -> i8*) and use
it for both the loop-variable alloca and the element load; fail fast when
the specialization name cannot be resolved instead of silently loading a
pointer.

Probe: `for v in list[int]` prints 10/20/30 and sums 60; the reporting
project compiles and runs without the MLIR failure; self-host 110/110;
ListTest, GenericTest3, PtrOpProbe and HashLibTest pass.
This commit is contained in:
TermiNexus committed 2026-11-02 11:10:20 +08:00
1 parent 49683fc881
commit 91d300d45f
1 file changed
+14 -3
+14 -3
View File
@@ -2023,11 +2023,22 @@ novirtual class StmtGenCifMixin:
if cnt_ptr is None: self.Gen.TypeGenErr.fatal_error(for_node, "list iteration: failed to locate __count__")
count_val: mlirlite.Value* = mlirlite.build_load(builder, i64_ty, cnt_ptr)
# loop-var alloca (element type i8*, matching inline list.get)
# loop-var alloca (the real element type: list[int] -> i32, list[str] -> i8*).
# A fixed i8* slot made `for i in list[int]` store a pointer-typed element and
# poisoned later reuse of the same name (e.g. a following `for i in range(6)`
# stored/compared integer 6 against an i8* slot).
lst_st: mlirlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(list_val)
lst_nm: str = None
if lst_st is not None: lst_nm = mlirlite.get_struct_name(lst_st)
elem_ty: mlirlite.LLVMType* = None
if lst_nm is not None: elem_ty = self.Gen.ExprGenName._list_elem_type_from_name(pool, lst_nm)
if elem_ty is None:
self.Gen.TypeGenErr.fatal_error(for_node, "list iteration: cannot determine the list element type (unresolved list[...] specialization)", "TypeError")
return 0
var_alloca: mlirlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name)
new_vars: int = 0
if var_alloca is None:
var_alloca = self.Gen.VarGen._alloca_at_entry(builder, i8_ptr_ty)
var_alloca = self.Gen.VarGen._alloca_at_entry(builder, elem_ty)
if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0: new_vars = 1
# implicit index variable (i64, aligned with __count__)
@@ -2071,7 +2082,7 @@ novirtual class StmtGenCifMixin:
esize: mlirlite.Value* = mlirlite.build_load(builder, i64_ty, epp)
offset: mlirlite.Value* = mlirlite.build_mul(builder, cur_idx, esize)
elem_addr: mlirlite.Value* = mlirlite.build_gep(builder, i8_ty, data_ptr, offset)
cur_elem: mlirlite.Value* = mlirlite.build_load(builder, i8_ptr_ty, elem_addr)
cur_elem: mlirlite.Value* = mlirlite.build_load(builder, elem_ty, elem_addr)
mlirlite.build_store(builder, cur_elem, var_alloca)
# save the old loop context and set break/continue targets