| ... | ... | @@ -5951,7 +5951,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 5951 | 5951 | } |
| 5952 | 5952 | const all_tags_handled = for (seen_fields) |seen_src| { |
| 5953 | 5953 | if (seen_src == null) break false; |
| 5954 | | } else true; |
| 5954 | } else !operand_ty.isNonexhaustiveEnum(); |
| 5955 | 5955 | |
| 5956 | 5956 | switch (special_prong) { |
| 5957 | 5957 | .none => { |
| ... | ... | @@ -9035,9 +9035,119 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 9035 | 9035 | }), |
| 9036 | 9036 | ); |
| 9037 | 9037 | }, |
| 9038 | | else => |t| return sema.fail(block, src, "TODO: implement zirTypeInfo for {s}", .{ |
| 9039 | | @tagName(t), |
| 9040 | | }), |
| 9038 | .Enum => { |
| 9039 | // TODO: look into memoizing this result. |
| 9040 | var int_tag_type_buffer: Type.Payload.Bits = undefined; |
| 9041 | const int_tag_ty = try ty.intTagType(&int_tag_type_buffer).copy(sema.arena); |
| 9042 | |
| 9043 | const is_exhaustive = if (ty.isNonexhaustiveEnum()) Value.@"false" else Value.@"true"; |
| 9044 | |
| 9045 | var fields_anon_decl = try block.startAnonDecl(); |
| 9046 | defer fields_anon_decl.deinit(); |
| 9047 | |
| 9048 | const enum_field_ty = t: { |
| 9049 | const enum_field_ty_decl = (try sema.namespaceLookup( |
| 9050 | block, |
| 9051 | src, |
| 9052 | type_info_ty.getNamespace().?, |
| 9053 | "EnumField", |
| 9054 | )).?; |
| 9055 | try sema.mod.declareDeclDependency(sema.owner_decl, enum_field_ty_decl); |
| 9056 | try sema.ensureDeclAnalyzed(enum_field_ty_decl); |
| 9057 | var buffer: Value.ToTypeBuffer = undefined; |
| 9058 | break :t try enum_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena()); |
| 9059 | }; |
| 9060 | |
| 9061 | const enum_fields = ty.enumFields(); |
| 9062 | const enum_field_vals = try fields_anon_decl.arena().alloc(Value, enum_fields.count()); |
| 9063 | |
| 9064 | for (enum_field_vals) |*field_val, i| { |
| 9065 | var tag_val_payload: Value.Payload.U32 = .{ |
| 9066 | .base = .{ .tag = .enum_field_index }, |
| 9067 | .data = @intCast(u32, i), |
| 9068 | }; |
| 9069 | const tag_val = Value.initPayload(&tag_val_payload.base); |
| 9070 | |
| 9071 | var buffer: Value.Payload.U64 = undefined; |
| 9072 | const int_val = try tag_val.enumToInt(ty, &buffer).copy(fields_anon_decl.arena()); |
| 9073 | |
| 9074 | const name = enum_fields.keys()[i]; |
| 9075 | const name_val = v: { |
| 9076 | var anon_decl = try block.startAnonDecl(); |
| 9077 | defer anon_decl.deinit(); |
| 9078 | const bytes = try anon_decl.arena().dupeZ(u8, name); |
| 9079 | const new_decl = try anon_decl.finish( |
| 9080 | try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), |
| 9081 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), |
| 9082 | ); |
| 9083 | break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl); |
| 9084 | }; |
| 9085 | |
| 9086 | const enum_field_fields = try fields_anon_decl.arena().create([2]Value); |
| 9087 | enum_field_fields.* = .{ |
| 9088 | // name: []const u8, |
| 9089 | name_val, |
| 9090 | // value: comptime_int, |
| 9091 | int_val, |
| 9092 | }; |
| 9093 | field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), enum_field_fields); |
| 9094 | } |
| 9095 | |
| 9096 | const fields_val = v: { |
| 9097 | const new_decl = try fields_anon_decl.finish( |
| 9098 | try Type.Tag.array.create(fields_anon_decl.arena(), .{ |
| 9099 | .len = enum_field_vals.len, |
| 9100 | .elem_type = enum_field_ty, |
| 9101 | }), |
| 9102 | try Value.Tag.array.create( |
| 9103 | fields_anon_decl.arena(), |
| 9104 | try fields_anon_decl.arena().dupe(Value, enum_field_vals), |
| 9105 | ), |
| 9106 | ); |
| 9107 | break :v try Value.Tag.decl_ref.create(sema.arena, new_decl); |
| 9108 | }; |
| 9109 | |
| 9110 | if (ty.getNamespace()) |namespace| { |
| 9111 | if (namespace.decls.count() != 0) { |
| 9112 | return sema.fail(block, src, "TODO: implement zirTypeInfo for Enum which has declarations", .{}); |
| 9113 | } |
| 9114 | } |
| 9115 | const decls_val = Value.initTag(.empty_array); |
| 9116 | |
| 9117 | const field_values = try sema.arena.create([5]Value); |
| 9118 | field_values.* = .{ |
| 9119 | // layout: ContainerLayout, |
| 9120 | try Value.Tag.enum_field_index.create( |
| 9121 | sema.arena, |
| 9122 | @enumToInt(std.builtin.TypeInfo.ContainerLayout.Auto), |
| 9123 | ), |
| 9124 | |
| 9125 | // tag_type: type, |
| 9126 | try Value.Tag.ty.create(sema.arena, int_tag_ty), |
| 9127 | // fields: []const EnumField, |
| 9128 | fields_val, |
| 9129 | // decls: []const Declaration, |
| 9130 | decls_val, |
| 9131 | // is_exhaustive: bool, |
| 9132 | is_exhaustive, |
| 9133 | }; |
| 9134 | |
| 9135 | return sema.addConstant( |
| 9136 | type_info_ty, |
| 9137 | try Value.Tag.@"union".create(sema.arena, .{ |
| 9138 | .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Enum)), |
| 9139 | .val = try Value.Tag.@"struct".create(sema.arena, field_values), |
| 9140 | }), |
| 9141 | ); |
| 9142 | }, |
| 9143 | .Struct => return sema.fail(block, src, "TODO: implement zirTypeInfo for Struct", .{}), |
| 9144 | .ErrorSet => return sema.fail(block, src, "TODO: implement zirTypeInfo for ErrorSet", .{}), |
| 9145 | .Union => return sema.fail(block, src, "TODO: implement zirTypeInfo for Union", .{}), |
| 9146 | .BoundFn => @panic("TODO remove this type from the language and compiler"), |
| 9147 | .Opaque => return sema.fail(block, src, "TODO: implement zirTypeInfo for Opaque", .{}), |
| 9148 | .Frame => return sema.fail(block, src, "TODO: implement zirTypeInfo for Frame", .{}), |
| 9149 | .AnyFrame => return sema.fail(block, src, "TODO: implement zirTypeInfo for AnyFrame", .{}), |
| 9150 | .Vector => return sema.fail(block, src, "TODO: implement zirTypeInfo for Vector", .{}), |
| 9041 | 9151 | } |
| 9042 | 9152 | } |
| 9043 | 9153 | |
| ... | ... | @@ -15153,13 +15263,13 @@ fn getBuiltin( |
| 15153 | 15263 | ); |
| 15154 | 15264 | const builtin_inst = try sema.analyzeLoad(block, src, opt_builtin_inst.?, src); |
| 15155 | 15265 | const builtin_ty = try sema.analyzeAsType(block, src, builtin_inst); |
| 15156 | | const opt_ty_inst = try sema.namespaceLookupRef( |
| 15266 | const opt_ty_decl = try sema.namespaceLookup( |
| 15157 | 15267 | block, |
| 15158 | 15268 | src, |
| 15159 | 15269 | builtin_ty.getNamespace().?, |
| 15160 | 15270 | name, |
| 15161 | 15271 | ); |
| 15162 | | return sema.analyzeLoad(block, src, opt_ty_inst.?, src); |
| 15272 | return sema.analyzeDeclVal(block, src, opt_ty_decl.?); |
| 15163 | 15273 | } |
| 15164 | 15274 | |
| 15165 | 15275 | fn getBuiltinType( |