@@ -11907,17 +11907,41 @@ pub const Interpreter = struct {
1190711907 }
1190811908 try value_stack.push(dest);
1190911909 } else {
11910- // Get element type from list_rt_var. The list type should be List(elem)
11911- // where vars[0] is backing and vars[1] is the element type.
11912- // The element type may be flex (e.g., Num *) which is fine - downstream
11913- // code like getRuntimeLayout will default flex to Dec as needed.
11910+ // Determine the element type for this non-empty list literal.
11911+ //
11912+ // Primary path: Extract from list type structure.
11913+ // The list type should be List(elem) where vars[0] is backing and
11914+ // vars[1] is the element type. The element type may be flex (e.g.,
11915+ // Num *) which is fine - downstream code like getRuntimeLayout will
11916+ // default flex to Dec as needed.
11917+ //
11918+ // Alternative path: Derive from first element's type.
11919+ // In polymorphic contexts (e.g., inside a for loop in a polymorphic
11920+ // function), the list type variable may resolve to a flex/rigid
11921+ // rather than a List(elem) structure. This happens due to union-find
11922+ // redirect chains in the type store. In this case, we determine the
11923+ // element type from the first element's compile-time type.
11924+ //
11925+ // This alternative is semantically correct because the element type
11926+ // of a list literal [e1, e2, ...] IS the type of its elements - the
11927+ // type checker explicitly unifies the list's element type with the
11928+ // first element's type (see Check.zig e_list handling).
1191411929 const list_resolved = self.runtime_types.resolveVar(list_rt_var);
11915- std.debug.assert(list_resolved.desc.content == .structure);
11916- std.debug.assert(list_resolved.desc.content.structure == .nominal_type);
11917- const nom = list_resolved.desc.content.structure.nominal_type;
11918- const vars = self.runtime_types.sliceVars(nom.vars.nonempty);
11919- std.debug.assert(vars.len == 2); // vars[0] = backing, vars[1] = element type
11920- const elem_rt_var = vars[1];
11930+ const elem_rt_var = blk: {
11931+ if (list_resolved.desc.content == .structure) {
11932+ if (list_resolved.desc.content.structure == .nominal_type) {
11933+ const nom = list_resolved.desc.content.structure.nominal_type;
11934+ const vars = self.runtime_types.sliceVars(nom.vars.nonempty);
11935+ if (vars.len == 2) {
11936+ // vars[0] = backing, vars[1] = element type
11937+ break :blk vars[1];
11938+ }
11939+ }
11940+ }
11941+ // List type is flex/rigid - derive element type from first element
11942+ const first_elem_ct_var = can.ModuleEnv.varFrom(elems[0]);
11943+ break :blk try self.translateTypeVar(self.env, first_elem_ct_var);
11944+ };
1192111945
1192211946 const elem_resolved = self.runtime_types.resolveVar(elem_rt_var);
1192311947 const elem_content = elem_resolved.desc.content;
0 commit comments