aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-07-14 23:59:29 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-07-20 12:19:16 -0700
commit0da66339096c21d9ca524ff7a0c11a5707b60041 (patch)
treee5c530e4c42e7ae4a6b65040da9e7ac7e3bae264 /src
parent1294ebe1f5eaca1f11d68284d1b96419d53253be (diff)
downloadzig-0da66339096c21d9ca524ff7a0c11a5707b60041.tar.gz
zig-0da66339096c21d9ca524ff7a0c11a5707b60041.zip
Sema: fix implementation of getTypeOf
and rename it to typeOf
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig467
1 files changed, 258 insertions, 209 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index d33d5bd49b..268f7bc903 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -199,65 +199,65 @@ pub fn analyzeBody(
.cmp_lt => try sema.zirCmp(block, inst, .lt),
.cmp_lte => try sema.zirCmp(block, inst, .lte),
.cmp_neq => try sema.zirCmp(block, inst, .neq),
- //.coerce_result_ptr => try sema.zirCoerceResultPtr(block, inst),
- //.decl_ref => try sema.zirDeclRef(block, inst),
- //.decl_val => try sema.zirDeclVal(block, inst),
- //.load => try sema.zirLoad(block, inst),
- //.elem_ptr => try sema.zirElemPtr(block, inst),
- //.elem_ptr_node => try sema.zirElemPtrNode(block, inst),
- //.elem_val => try sema.zirElemVal(block, inst),
- //.elem_val_node => try sema.zirElemValNode(block, inst),
- //.elem_type => try sema.zirElemType(block, inst),
- //.enum_literal => try sema.zirEnumLiteral(block, inst),
- //.enum_to_int => try sema.zirEnumToInt(block, inst),
- //.int_to_enum => try sema.zirIntToEnum(block, inst),
- //.err_union_code => try sema.zirErrUnionCode(block, inst),
- //.err_union_code_ptr => try sema.zirErrUnionCodePtr(block, inst),
- //.err_union_payload_safe => try sema.zirErrUnionPayload(block, inst, true),
- //.err_union_payload_safe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, true),
- //.err_union_payload_unsafe => try sema.zirErrUnionPayload(block, inst, false),
- //.err_union_payload_unsafe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, false),
- //.error_union_type => try sema.zirErrorUnionType(block, inst),
- //.error_value => try sema.zirErrorValue(block, inst),
- //.error_to_int => try sema.zirErrorToInt(block, inst),
- //.int_to_error => try sema.zirIntToError(block, inst),
- //.field_ptr => try sema.zirFieldPtr(block, inst),
- //.field_ptr_named => try sema.zirFieldPtrNamed(block, inst),
- //.field_val => try sema.zirFieldVal(block, inst),
- //.field_val_named => try sema.zirFieldValNamed(block, inst),
- //.func => try sema.zirFunc(block, inst, false),
- //.func_inferred => try sema.zirFunc(block, inst, true),
- //.import => try sema.zirImport(block, inst),
- //.indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst),
- //.int => try sema.zirInt(block, inst),
- //.int_big => try sema.zirIntBig(block, inst),
- //.float => try sema.zirFloat(block, inst),
- //.float128 => try sema.zirFloat128(block, inst),
- //.int_type => try sema.zirIntType(block, inst),
- //.is_non_err => try sema.zirIsNonErr(block, inst),
- //.is_non_err_ptr => try sema.zirIsNonErrPtr(block, inst),
- //.is_non_null => try sema.zirIsNonNull(block, inst),
- //.is_non_null_ptr => try sema.zirIsNonNullPtr(block, inst),
- //.loop => try sema.zirLoop(block, inst),
- //.merge_error_sets => try sema.zirMergeErrorSets(block, inst),
- //.negate => try sema.zirNegate(block, inst, .sub),
- //.negate_wrap => try sema.zirNegate(block, inst, .subwrap),
- //.optional_payload_safe => try sema.zirOptionalPayload(block, inst, true),
- //.optional_payload_safe_ptr => try sema.zirOptionalPayloadPtr(block, inst, true),
- //.optional_payload_unsafe => try sema.zirOptionalPayload(block, inst, false),
- //.optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, inst, false),
- //.optional_type => try sema.zirOptionalType(block, inst),
- //.param_type => try sema.zirParamType(block, inst),
- //.ptr_type => try sema.zirPtrType(block, inst),
- //.ptr_type_simple => try sema.zirPtrTypeSimple(block, inst),
- //.ref => try sema.zirRef(block, inst),
- //.ret_err_value_code => try sema.zirRetErrValueCode(block, inst),
- //.shl => try sema.zirShl(block, inst),
- //.shr => try sema.zirShr(block, inst),
- //.slice_end => try sema.zirSliceEnd(block, inst),
- //.slice_sentinel => try sema.zirSliceSentinel(block, inst),
- //.slice_start => try sema.zirSliceStart(block, inst),
- //.str => try sema.zirStr(block, inst),
+ .coerce_result_ptr => try sema.zirCoerceResultPtr(block, inst),
+ .decl_ref => try sema.zirDeclRef(block, inst),
+ .decl_val => try sema.zirDeclVal(block, inst),
+ .load => try sema.zirLoad(block, inst),
+ .elem_ptr => try sema.zirElemPtr(block, inst),
+ .elem_ptr_node => try sema.zirElemPtrNode(block, inst),
+ .elem_val => try sema.zirElemVal(block, inst),
+ .elem_val_node => try sema.zirElemValNode(block, inst),
+ .elem_type => try sema.zirElemType(block, inst),
+ .enum_literal => try sema.zirEnumLiteral(block, inst),
+ .enum_to_int => try sema.zirEnumToInt(block, inst),
+ .int_to_enum => try sema.zirIntToEnum(block, inst),
+ .err_union_code => try sema.zirErrUnionCode(block, inst),
+ .err_union_code_ptr => try sema.zirErrUnionCodePtr(block, inst),
+ .err_union_payload_safe => try sema.zirErrUnionPayload(block, inst, true),
+ .err_union_payload_safe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, true),
+ .err_union_payload_unsafe => try sema.zirErrUnionPayload(block, inst, false),
+ .err_union_payload_unsafe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, false),
+ .error_union_type => try sema.zirErrorUnionType(block, inst),
+ .error_value => try sema.zirErrorValue(block, inst),
+ .error_to_int => try sema.zirErrorToInt(block, inst),
+ .int_to_error => try sema.zirIntToError(block, inst),
+ .field_ptr => try sema.zirFieldPtr(block, inst),
+ .field_ptr_named => try sema.zirFieldPtrNamed(block, inst),
+ .field_val => try sema.zirFieldVal(block, inst),
+ .field_val_named => try sema.zirFieldValNamed(block, inst),
+ .func => try sema.zirFunc(block, inst, false),
+ .func_inferred => try sema.zirFunc(block, inst, true),
+ .import => try sema.zirImport(block, inst),
+ .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst),
+ .int => try sema.zirInt(block, inst),
+ .int_big => try sema.zirIntBig(block, inst),
+ .float => try sema.zirFloat(block, inst),
+ .float128 => try sema.zirFloat128(block, inst),
+ .int_type => try sema.zirIntType(block, inst),
+ .is_non_err => try sema.zirIsNonErr(block, inst),
+ .is_non_err_ptr => try sema.zirIsNonErrPtr(block, inst),
+ .is_non_null => try sema.zirIsNonNull(block, inst),
+ .is_non_null_ptr => try sema.zirIsNonNullPtr(block, inst),
+ .loop => try sema.zirLoop(block, inst),
+ .merge_error_sets => try sema.zirMergeErrorSets(block, inst),
+ .negate => try sema.zirNegate(block, inst, .sub),
+ .negate_wrap => try sema.zirNegate(block, inst, .subwrap),
+ .optional_payload_safe => try sema.zirOptionalPayload(block, inst, true),
+ .optional_payload_safe_ptr => try sema.zirOptionalPayloadPtr(block, inst, true),
+ .optional_payload_unsafe => try sema.zirOptionalPayload(block, inst, false),
+ .optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, inst, false),
+ .optional_type => try sema.zirOptionalType(block, inst),
+ .param_type => try sema.zirParamType(block, inst),
+ .ptr_type => try sema.zirPtrType(block, inst),
+ .ptr_type_simple => try sema.zirPtrTypeSimple(block, inst),
+ .ref => try sema.zirRef(block, inst),
+ .ret_err_value_code => try sema.zirRetErrValueCode(block, inst),
+ .shl => try sema.zirShl(block, inst),
+ .shr => try sema.zirShr(block, inst),
+ .slice_end => try sema.zirSliceEnd(block, inst),
+ .slice_sentinel => try sema.zirSliceSentinel(block, inst),
+ .slice_start => try sema.zirSliceStart(block, inst),
+ .str => try sema.zirStr(block, inst),
//.switch_block => try sema.zirSwitchBlock(block, inst, false, .none),
//.switch_block_multi => try sema.zirSwitchBlockMulti(block, inst, false, .none),
//.switch_block_else => try sema.zirSwitchBlock(block, inst, false, .@"else"),
@@ -536,7 +536,7 @@ pub fn analyzeBody(
},
else => |t| @panic(@tagName(t)),
};
- if (sema.getTypeOf(air_inst).isNoReturn())
+ if (sema.typeOf(air_inst).isNoReturn())
return always_noreturn;
try map.put(sema.gpa, inst, air_inst);
i += 1;
@@ -620,10 +620,10 @@ fn resolveConstString(
pub fn resolveType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {
const air_inst = sema.resolveInst(zir_ref);
- return sema.resolveAirAsType(block, src, air_inst);
+ return sema.analyzeAsType(block, src, air_inst);
}
-fn resolveAirAsType(
+fn analyzeAsType(
sema: *Sema,
block: *Scope.Block,
src: LazySrcLoc,
@@ -664,26 +664,26 @@ fn resolvePossiblyUndefinedValue(
sema: *Sema,
block: *Scope.Block,
src: LazySrcLoc,
- air_ref: Air.Inst.Ref,
+ inst: Air.Inst.Ref,
) CompileError!?Value {
- const ty = sema.getTypeOf(air_ref);
- if (try sema.typeHasOnePossibleValue(block, src, ty)) |opv| {
- return opv;
- }
// First section of indexes correspond to a set number of constant values.
- var i: usize = @enumToInt(air_ref);
+ var i: usize = @enumToInt(inst);
if (i < Air.Inst.Ref.typed_value_map.len) {
return Air.Inst.Ref.typed_value_map[i].val;
}
i -= Air.Inst.Ref.typed_value_map.len;
+ if (try sema.typeHasOnePossibleValue(block, src, sema.typeOf(inst))) |opv| {
+ return opv;
+ }
+
switch (sema.air_instructions.items(.tag)[i]) {
.constant => {
const ty_pl = sema.air_instructions.items(.data)[i].ty_pl;
return sema.air_values.items[ty_pl.payload];
},
.const_ty => {
- return sema.air_instructions.items(.data)[i].ty.toValue(undefined) catch unreachable;
+ return try sema.air_instructions.items(.data)[i].ty.toValue(sema.arena);
},
else => return null,
}
@@ -739,7 +739,7 @@ pub fn resolveInstConst(
const air_ref = sema.resolveInst(zir_ref);
const val = try sema.resolveConstValue(block, src, air_ref);
return TypedValue{
- .ty = sema.getTypeOf(air_ref),
+ .ty = sema.typeOf(air_ref),
.val = val,
};
}
@@ -1230,7 +1230,7 @@ fn ensureResultUsed(
operand: Air.Inst.Ref,
src: LazySrcLoc,
) CompileError!void {
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
switch (operand_ty.zigTypeTag()) {
.Void, .NoReturn => return,
else => return sema.mod.fail(&block.base, src, "expression value is ignored", .{}),
@@ -1244,7 +1244,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const operand = sema.resolveInst(inst_data.operand);
const src = inst_data.src();
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
switch (operand_ty.zigTypeTag()) {
.ErrorSet, .ErrorUnion => return sema.mod.fail(&block.base, src, "error is discarded", .{}),
else => return,
@@ -1259,7 +1259,7 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co
const src = inst_data.src();
const array_ptr = sema.resolveInst(inst_data.operand);
- const elem_ty = sema.getTypeOf(array_ptr).elemType();
+ const elem_ty = sema.typeOf(array_ptr).elemType();
if (!elem_ty.isIndexable()) {
const cond_src: LazySrcLoc = .{ .node_offset_for_cond = inst_data.src_node };
const msg = msg: {
@@ -1282,7 +1282,8 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co
return sema.mod.failWithOwnedErrorMsg(&block.base, msg);
}
const result_ptr = try sema.namedFieldPtr(block, src, array_ptr, "len", src);
- return sema.analyzeLoad(block, src, result_ptr, result_ptr.src);
+ const result_ptr_src = src;
+ return sema.analyzeLoad(block, src, result_ptr, result_ptr_src);
}
fn zirArg(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -1630,7 +1631,7 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
const inst_data = sema.code.instructions.items(.data)[inst].param_type;
const fn_inst = sema.resolveInst(inst_data.callee);
- const fn_inst_ty = sema.getTypeOf(fn_inst);
+ const fn_inst_ty = sema.typeOf(fn_inst);
const param_index = inst_data.param_index;
const fn_ty: Type = switch (fn_inst_ty.zigTypeTag()) {
@@ -1859,7 +1860,7 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil
sema.air_instructions.items(.data)[loop_inst].ty_pl.payload = sema.addExtraAssumeCapacity(
Air.Block{ .body_len = @intCast(u32, loop_block.instructions.items.len) },
);
- sema.air_extra.appendAssumeCapacity(loop_block.instructions.items);
+ sema.air_extra.appendSliceAssumeCapacity(loop_block.instructions.items);
return sema.analyzeBlockBody(parent_block, src, &child_block, merges);
}
@@ -1957,7 +1958,7 @@ fn analyzeBlockBody(
// Blocks must terminate with noreturn instruction.
assert(child_block.instructions.items.len != 0);
- assert(sema.getTypeOf(indexToRef(child_block.instructions.items[child_block.instructions.items.len - 1])).isNoReturn());
+ assert(sema.typeOf(indexToRef(child_block.instructions.items[child_block.instructions.items.len - 1])).isNoReturn());
if (merges.results.items.len == 0) {
// No need for a block instruction. We can put the new instructions
@@ -1999,7 +2000,7 @@ fn analyzeBlockBody(
for (merges.br_list.items) |br| {
const br_operand = sema.air_instructions.items(.data)[br].br.operand;
const br_operand_src = src;
- const br_operand_ty = sema.getTypeOf(br_operand);
+ const br_operand_ty = sema.typeOf(br_operand);
if (br_operand_ty.eql(resolved_ty)) {
// No type coercion needed.
continue;
@@ -2252,7 +2253,7 @@ fn analyzeCall(
ensure_result_used: bool,
args: []const Air.Inst.Ref,
) CompileError!Air.Inst.Ref {
- const func_ty = sema.getTypeOf(func);
+ const func_ty = sema.typeOf(func);
if (func_ty.zigTypeTag() != .Fn)
return sema.mod.fail(&block.base, func_src, "type '{}' not a function", .{func_ty});
@@ -2606,8 +2607,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com
const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
const lhs = sema.resolveInst(extra.lhs);
const rhs = sema.resolveInst(extra.rhs);
- const lhs_ty = sema.getTypeOf(lhs);
- const rhs_ty = sema.getTypeOf(rhs);
+ const lhs_ty = sema.typeOf(lhs);
+ const rhs_ty = sema.typeOf(rhs);
if (rhs_ty.zigTypeTag() == .Bool and lhs_ty.zigTypeTag() == .Bool) {
const msg = msg: {
const msg = try sema.mod.errMsg(&block.base, lhs_src, "expected error set type, found 'bool'", .{});
@@ -2699,7 +2700,7 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
const src = inst_data.src();
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
const operand = sema.resolveInst(inst_data.operand);
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {
.Enum => operand,
@@ -2720,7 +2721,7 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
});
},
};
- const enum_tag_ty = sema.getTypeOf(enum_tag);
+ const enum_tag_ty = sema.typeOf(enum_tag);
var int_tag_type_buffer: Type.Payload.Bits = undefined;
const int_tag_ty = try enum_tag_ty.intTagType(&int_tag_type_buffer).copy(arena);
@@ -2821,7 +2822,7 @@ fn zirOptionalPayloadPtr(
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const optional_ptr = sema.resolveInst(inst_data.operand);
- const optional_ptr_ty = sema.getTypeOf(optional_ptr);
+ const optional_ptr_ty = sema.typeOf(optional_ptr);
assert(optional_ptr_ty.zigTypeTag() == .Pointer);
const src = inst_data.src();
@@ -2863,7 +2864,7 @@ fn zirOptionalPayload(
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand = sema.resolveInst(inst_data.operand);
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
const opt_type = operand_ty;
if (opt_type.zigTypeTag() != .Optional) {
return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type});
@@ -2900,7 +2901,7 @@ fn zirErrUnionPayload(
const src = inst_data.src();
const operand = sema.resolveInst(inst_data.operand);
const operand_src = src;
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
if (operand_ty.zigTypeTag() != .ErrorUnion)
return sema.mod.fail(&block.base, operand_src, "expected error union type, found '{}'", .{operand_ty});
@@ -2936,7 +2937,7 @@ fn zirErrUnionPayloadPtr(
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand = sema.resolveInst(inst_data.operand);
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
assert(operand_ty.zigTypeTag() == .Pointer);
if (operand_ty.elemType().zigTypeTag() != .ErrorUnion)
@@ -2976,7 +2977,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand = sema.resolveInst(inst_data.operand);
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
if (operand_ty.zigTypeTag() != .ErrorUnion)
return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand_ty});
@@ -3000,7 +3001,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand = sema.resolveInst(inst_data.operand);
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
assert(operand_ty.zigTypeTag() == .Pointer);
if (operand_ty.elemType().zigTypeTag() != .ErrorUnion)
@@ -3026,7 +3027,7 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
const src = inst_data.src();
const operand = sema.resolveInst(inst_data.operand);
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
if (operand_ty.zigTypeTag() != .ErrorUnion)
return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand_ty});
if (operand_ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) {
@@ -3214,7 +3215,6 @@ fn funcCommon(
.state = anal_state,
.zir_body_inst = body_inst,
.owner_decl = sema.owner_decl,
- .body = undefined,
.lbrace_line = src_locs.lbrace_line,
.rbrace_line = src_locs.rbrace_line,
.lbrace_column = @truncate(u16, src_locs.columns),
@@ -3283,12 +3283,13 @@ fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
const field_name = sema.code.nullTerminatedString(extra.field_name_start);
const object = sema.resolveInst(extra.lhs);
- const object_ptr = if (sema.getTypeOf(object).zigTypeTag() == .Pointer)
+ const object_ptr = if (sema.typeOf(object).zigTypeTag() == .Pointer)
object
else
try sema.analyzeRef(block, src, object);
const result_ptr = try sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);
- return sema.analyzeLoad(block, src, result_ptr, result_ptr.src);
+ const result_ptr_src = src;
+ return sema.analyzeLoad(block, src, result_ptr, result_ptr_src);
}
fn zirFieldPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -3356,7 +3357,7 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
),
};
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
switch (operand_ty.zigTypeTag()) {
.ComptimeInt, .Int => {},
else => return sema.mod.fail(
@@ -3414,7 +3415,7 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
),
};
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
switch (operand_ty.zigTypeTag()) {
.ComptimeFloat, .Float, .ComptimeInt => {},
else => return sema.mod.fail(
@@ -3440,7 +3441,7 @@ fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
const bin_inst = sema.code.instructions.items(.data)[inst].bin;
const array = sema.resolveInst(bin_inst.lhs);
- const array_ty = sema.getTypeOf(array);
+ const array_ty = sema.typeOf(array);
const array_ptr = if (array_ty.zigTypeTag() == .Pointer)
array
else
@@ -3459,7 +3460,7 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil
const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const array = sema.resolveInst(extra.lhs);
- const array_ty = sema.getTypeOf(array);
+ const array_ty = sema.typeOf(array);
const array_ptr = if (array_ty.zigTypeTag() == .Pointer)
array
else
@@ -3502,7 +3503,7 @@ fn zirSliceStart(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile
const array_ptr = sema.resolveInst(extra.lhs);
const start = sema.resolveInst(extra.start);
- return sema.analyzeSlice(block, src, array_ptr, start, null, null, .unneeded);
+ return sema.analyzeSlice(block, src, array_ptr, start, .none, .none, .unneeded);
}
fn zirSliceEnd(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -3516,7 +3517,7 @@ fn zirSliceEnd(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
const start = sema.resolveInst(extra.start);
const end = sema.resolveInst(extra.end);
- return sema.analyzeSlice(block, src, array_ptr, start, end, null, .unneeded);
+ return sema.analyzeSlice(block, src, array_ptr, start, end, .none, .unneeded);
}
fn zirSliceSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -3668,7 +3669,7 @@ fn analyzeSwitch(
const src: LazySrcLoc = .{ .node_offset = src_node_offset };
const special_prong_src: LazySrcLoc = .{ .node_offset_switch_special_prong = src_node_offset };
const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
// Validate usage of '_' prongs.
if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) {
@@ -4590,8 +4591,8 @@ fn zirBitwise(
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = sema.resolveInst(extra.lhs);
const rhs = sema.resolveInst(extra.rhs);
- const lhs_ty = sema.getTypeOf(lhs);
- const rhs_ty = sema.getTypeOf(rhs);
+ const lhs_ty = sema.typeOf(lhs);
+ const rhs_ty = sema.typeOf(rhs);
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
const resolved_type = try sema.resolvePeerTypes(block, src, instructions);
@@ -4722,8 +4723,8 @@ fn analyzeArithmetic(
lhs_src: LazySrcLoc,
rhs_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
- const lhs_ty = sema.getTypeOf(lhs);
- const rhs_ty = sema.getTypeOf(rhs);
+ const lhs_ty = sema.typeOf(lhs);
+ const rhs_ty = sema.typeOf(rhs);
if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) {
if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) {
return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
@@ -4944,8 +4945,8 @@ fn zirCmp(
.eq, .neq => true,
else => false,
};
- const lhs_ty = sema.getTypeOf(lhs);
- const rhs_ty = sema.getTypeOf(rhs);
+ const lhs_ty = sema.typeOf(lhs);
+ const rhs_ty = sema.typeOf(rhs);
const lhs_ty_tag = lhs_ty.zigTypeTag();
const rhs_ty_tag = rhs_ty.zigTypeTag();
if (is_equality_cmp and lhs_ty_tag == .Null and rhs_ty_tag == .Null) {
@@ -5007,8 +5008,8 @@ fn zirCmp(
if (!is_equality_cmp) {
return mod.fail(&block.base, src, "{s} operator not allowed for types", .{@tagName(op)});
}
- const lhs_as_type = try sema.resolveAirAsType(block, lhs_src, lhs);
- const rhs_as_type = try sema.resolveAirAsType(block, rhs_src, rhs);
+ const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs);
+ const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs);
if (lhs_as_type.eql(rhs_as_type) == (op == .eq)) {
return Air.Inst.Ref.bool_true;
} else {
@@ -5144,7 +5145,7 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro
const zir_datas = sema.code.instructions.items(.data);
const inst_data = zir_datas[inst].un_node;
const operand = sema.resolveInst(inst_data.operand);
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
return sema.addType(operand_ty);
}
@@ -6375,7 +6376,7 @@ fn addSafetyCheck(
const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len);
const cond_br_inst = block_inst + 1;
const br_inst = cond_br_inst + 1;
- sema.air_instructions.appendAssumeCapacity(gpa, .{
+ sema.air_instructions.appendAssumeCapacity(.{
.tag = .block,
.data = .{ .ty_pl = .{
.ty = .void_type,
@@ -6386,7 +6387,7 @@ fn addSafetyCheck(
});
sema.air_extra.appendAssumeCapacity(cond_br_inst);
- sema.air_instructions.appendAssumeCapacity(gpa, .{
+ sema.air_instructions.appendAssumeCapacity(.{
.tag = .cond_br,
.data = .{ .pl_op = .{
.operand = ok,
@@ -6399,7 +6400,7 @@ fn addSafetyCheck(
sema.air_extra.appendAssumeCapacity(br_inst);
sema.air_extra.appendSliceAssumeCapacity(fail_block.instructions.items);
- sema.air_instructions.appendAssumeCapacity(gpa, .{
+ sema.air_instructions.appendAssumeCapacity(.{
.tag = .br,
.data = .{ .br = .{
.block_inst = block_inst,
@@ -6497,9 +6498,11 @@ fn namedFieldPtr(
const mod = sema.mod;
const arena = sema.arena;
- const elem_ty = switch (object_ptr.ty.zigTypeTag()) {
- .Pointer => object_ptr.ty.elemType(),
- else => return mod.fail(&block.base, object_ptr.src, "expected pointer, found '{}'", .{object_ptr.ty}),
+ const object_ptr_src = src; // TODO better source location
+ const object_ptr_ty = sema.typeOf(object_ptr);
+ const elem_ty = switch (object_ptr_ty.zigTypeTag()) {
+ .Pointer => object_ptr_ty.elemType(),
+ else => return mod.fail(&block.base, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty}),
};
switch (elem_ty.zigTypeTag()) {
.Array => {
@@ -6545,9 +6548,9 @@ fn namedFieldPtr(
}
},
.Type => {
- _ = try sema.resolveConstValue(block, object_ptr.src, object_ptr);
- const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr.src);
- const val = result.value().?;
+ _ = try sema.resolveConstValue(block, object_ptr_src, object_ptr);
+ const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
+ const val = (sema.resolveDefinedValue(block, src, result) catch unreachable).?;
const child_type = try val.toType(arena);
switch (child_type.zigTypeTag()) {
.ErrorSet => {
@@ -6694,7 +6697,16 @@ fn analyzeStructFieldPtr(
}
try sema.requireRuntimeBlock(block, src);
- return block.addStructFieldPtr(src, ptr_field_ty, struct_ptr, @intCast(u32, field_index));
+ return block.addInst(.{
+ .tag = .struct_field_ptr,
+ .data = .{ .ty_pl = .{
+ .ty = try sema.addType(ptr_field_ty),
+ .payload = try sema.addExtra(Air.StructField{
+ .struct_ptr = struct_ptr,
+ .field_index = @intCast(u32, field_index),
+ }),
+ } },
+ });
}
fn analyzeUnionFieldPtr(
@@ -6742,16 +6754,18 @@ fn elemPtr(
elem_index: Air.Inst.Ref,
elem_index_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
- const array_ty = switch (array_ptr.ty.zigTypeTag()) {
- .Pointer => array_ptr.ty.elemType(),
- else => return sema.mod.fail(&block.base, array_ptr.src, "expected pointer, found '{}'", .{array_ptr.ty}),
+ const array_ptr_src = src; // TODO better source location
+ const array_ptr_ty = sema.typeOf(array_ptr);
+ const array_ty = switch (array_ptr_ty.zigTypeTag()) {
+ .Pointer => array_ptr_ty.elemType(),
+ else => return sema.mod.fail(&block.base, array_ptr_src, "expected pointer, found '{}'", .{array_ptr_ty}),
};
if (!array_ty.isIndexable()) {
return sema.mod.fail(&block.base, src, "array access of non-array type '{}'", .{array_ty});
}
if (array_ty.isSinglePointer() and array_ty.elemType().zigTypeTag() == .Array) {
// we have to deref the ptr operand to get the actual array pointer
- const array_ptr_deref = try sema.analyzeLoad(block, src, array_ptr, array_ptr.src);
+ const array_ptr_deref = try sema.analyzeLoad(block, src, array_ptr, array_ptr_src);
return sema.elemPtrArray(block, src, array_ptr_deref, elem_index, elem_index_src);
}
if (array_ty.zigTypeTag() == .Array) {
@@ -6776,7 +6790,7 @@ fn elemPtrArray(
// @intCast here because it would have been impossible to construct a value that
// required a larger index.
const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64));
- const pointee_type = array_ptr.ty.elemType().elemType();
+ const pointee_type = sema.typeOf(array_ptr).elemType().elemType();
return sema.addConstant(
try Type.Tag.single_const_pointer.create(sema.arena, pointee_type),
@@ -6800,7 +6814,7 @@ fn coerce(
return sema.coerceVarArgParam(block, inst, inst_src);
}
- const inst_ty = sema.getTypeOf(inst);
+ const inst_ty = sema.typeOf(inst);
// If the types are the same, we can return the operand.
if (dest_type.eql(inst_ty))
return inst;
@@ -7021,7 +7035,7 @@ fn coerceVarArgParam(
inst: Air.Inst.Ref,
inst_src: LazySrcLoc,
) !Air.Inst.Ref {
- const inst_ty = sema.getTypeOf(inst);
+ const inst_ty = sema.typeOf(inst);
switch (inst_ty.zigTypeTag()) {
.ComptimeInt, .ComptimeFloat => return sema.mod.fail(&block.base, inst_src, "integer and float literals in var args function must be casted", .{}),
else => {},
@@ -7170,8 +7184,8 @@ fn analyzeRef(
src: LazySrcLoc,
operand: Air.Inst.Ref,
) CompileError!Air.Inst.Ref {
- const operand_ty = sema.getTypeOf(operand);
- const ptr_type = try sema.mod.simplePtrType(sema.arena, operand_ty, false, .One);
+ const operand_ty = sema.typeOf(operand);
+ const ptr_type = try Module.simplePtrType(sema.arena, operand_ty, false, .One);
if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |val| {
return sema.addConstant(ptr_type, try Value.Tag.ref_val.create(sema.arena, val));
@@ -7188,7 +7202,7 @@ fn analyzeLoad(
ptr: Air.Inst.Ref,
ptr_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
- const ptr_ty = sema.getTypeOf(ptr);
+ const ptr_ty = sema.typeOf(ptr);
const elem_ty = switch (ptr_ty.zigTypeTag()) {
.Pointer => ptr_ty.elemType(),
else => return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr_ty}),
@@ -7235,7 +7249,7 @@ fn analyzeIsNonErr(
src: LazySrcLoc,
operand: Air.Inst.Ref,
) CompileError!Air.Inst.Ref {
- const operand_ty = sema.getTypeOf(operand);
+ const operand_ty = sema.typeOf(operand);
const ot = operand_ty.zigTypeTag();
if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true;
if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;
@@ -7261,13 +7275,14 @@ fn analyzeSlice(
src: LazySrcLoc,
array_ptr: Air.Inst.Ref,
start: Air.Inst.Ref,
- end_opt: ?Air.Inst.Index,
- sentinel_opt: ?Air.Inst.Index,
+ end_opt: Air.Inst.Ref,
+ sentinel_opt: Air.Inst.Ref,
sentinel_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
- const ptr_child = switch (array_ptr.ty.zigTypeTag()) {
- .Pointer => array_ptr.ty.elemType(),
- else => return sema.mod.fail(&block.base, src, "expected pointer, found '{}'", .{array_ptr.ty}),
+ const array_ptr_ty = sema.typeOf(array_ptr);
+ const ptr_child = switch (array_ptr_ty.zigTypeTag()) {
+ .Pointer => array_ptr_ty.elemType(),
+ else => return sema.mod.fail(&block.base, src, "expected pointer, found '{}'", .{array_ptr_ty}),
};
var array_type = ptr_child;
@@ -7287,15 +7302,15 @@ fn analyzeSlice(
else => return sema.mod.fail(&block.base, src, "slice of non-array type '{}'", .{ptr_child}),
};
- const slice_sentinel = if (sentinel_opt) |sentinel| blk: {
- const casted = try sema.coerce(block, elem_type, sentinel, sentinel.src);
+ const slice_sentinel = if (sentinel_opt != .none) blk: {
+ const casted = try sema.coerce(block, elem_type, sentinel_opt, sentinel_src);
break :blk try sema.resolveConstValue(block, sentinel_src, casted);
} else null;
var return_ptr_size: std.builtin.TypeInfo.Pointer.Size = .Slice;
var return_elem_type = elem_type;
- if (end_opt) |end| {
- if (try sema.resolveDefinedValue(block, src, end)) |end_val| {
+ if (end_opt != .none) {
+ if (try sema.resolveDefinedValue(block, src, end_opt)) |end_val| {
if (try sema.resolveDefinedValue(block, src, start)) |start_val| {
const start_u64 = start_val.toUnsignedInt();
const end_u64 = end_val.toUnsignedInt();
@@ -7316,7 +7331,7 @@ fn analyzeSlice(
const return_type = try sema.mod.ptrType(
sema.arena,
return_elem_type,
- if (end_opt == null) slice_sentinel else null,
+ if (end_opt == .none) slice_sentinel else null,
0, // TODO alignment
0,
0,
@@ -7341,8 +7356,8 @@ fn cmpNumeric(
lhs_src: LazySrcLoc,
rhs_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
- const lhs_ty = sema.getTypeOf(lhs);
- const rhs_ty = sema.getTypeOf(rhs);
+ const lhs_ty = sema.typeOf(lhs);
+ const rhs_ty = sema.typeOf(rhs);
assert(lhs_ty.isNumeric());
assert(rhs_ty.isNumeric());
@@ -7609,14 +7624,14 @@ fn resolvePeerTypes(
return Type.initTag(.noreturn);
if (instructions.len == 1)
- return sema.getTypeOf(instructions[0]);
+ return sema.typeOf(instructions[0]);
const target = sema.mod.getTarget();
var chosen = instructions[0];
for (instructions[1..]) |candidate| {
- const candidate_ty = sema.getTypeOf(candidate);
- const chosen_ty = sema.getTypeOf(chosen);
+ const candidate_ty = sema.typeOf(candidate);
+ const chosen_ty = sema.typeOf(chosen);
if (candidate_ty.eql(chosen_ty))
continue;
if (candidate_ty.zigTypeTag() == .NoReturn)
@@ -7677,7 +7692,7 @@ fn resolvePeerTypes(
return sema.mod.fail(&block.base, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty });
}
- return sema.getTypeOf(chosen);
+ return sema.typeOf(chosen);
}
fn resolveTypeFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) CompileError!Type {
@@ -7753,7 +7768,7 @@ fn getBuiltin(
"builtin",
);
const builtin_inst = try sema.analyzeLoad(block, src, opt_builtin_inst.?, src);
- const builtin_ty = try sema.resolveAirAsType(block, src, builtin_inst);
+ const builtin_ty = try sema.analyzeAsType(block, src, builtin_inst);
const opt_ty_inst = try sema.analyzeNamespaceLookup(
block,
src,
@@ -7770,7 +7785,7 @@ fn getBuiltinType(
name: []const u8,
) CompileError!Type {
const ty_inst = try sema.getBuiltin(block, src, name);
- return sema.resolveAirAsType(block, src, ty_inst);
+ return sema.analyzeAsType(block, src, ty_inst);
}
/// There is another implementation of this in `Type.onePossibleValue`. This one
@@ -7970,70 +7985,104 @@ fn enumFieldSrcLoc(
} else unreachable;
}
+/// This is only meant to be called by `typeOf`.
+fn analyzeAsTypeInfallible(sema: *Sema, inst: Air.Inst.Ref) Type {
+ var i: usize = @enumToInt(inst);
+ if (i < Air.Inst.Ref.typed_value_map.len) {
+ return Air.Inst.Ref.typed_value_map[i].val.toType(undefined) catch unreachable;
+ }
+ i -= Air.Inst.Ref.typed_value_map.len;
+ assert(sema.air_instructions.items(.tag)[i] == .const_ty);
+ return sema.air_instructions.items(.data)[i].ty;
+}
+
/// Returns the type of the AIR instruction.
-fn getTypeOf(sema: *Sema, air_ref: Air.Inst.Ref) Type {
- switch (air_ref) {
- .none => unreachable,
- .u8_type => return Type.initTag(.u8),
- .i8_type => return Type.initTag(.i8),
- .u16_type => return Type.initTag(.u16),
- .i16_type => return Type.initTag(.i16),
- .u32_type => return Type.initTag(.u32),
- .i32_type => return Type.initTag(.i32),
- .u64_type => return Type.initTag(.u64),
- .i64_type => return Type.initTag(.i64),
- .u128_type => return Type.initTag(.u128),
- .i128_type => return Type.initTag(.i128),
- .usize_type => return Type.initTag(.usize),
- .isize_type => return Type.initTag(.isize),
- .c_short_type => return Type.initTag(.c_short),
- .c_ushort_type => return Type.initTag(.c_ushort),
- .c_int_type => return Type.initTag(.c_int),
- .c_uint_type => return Type.initTag(.c_uint),
- .c_long_type => return Type.initTag(.c_long),
- .c_ulong_type => return Type.initTag(.c_ulong),
- .c_longlong_type => return Type.initTag(.c_longlong),
- .c_ulonglong_type => return Type.initTag(.c_ulonglong),
- .c_longdouble_type => return Type.initTag(.c_longdouble),
- .f16_type => return Type.initTag(.f16),
- .f32_type => return Type.initTag(.f32),
- .f64_type => return Type.initTag(.f64),
- .f128_type => return Type.initTag(.f128),
- .c_void_type => return Type.initTag(.c_void),
- .bool_type => return Type.initTag(.bool),
- .void_type => return Type.initTag(.void),
- .type_type => return Type.initTag(.type),
- .anyerror_type => return Type.initTag(.anyerror),
- .comptime_int_type => return Type.initTag(.comptime_int),
- .comptime_float_type => return Type.initTag(.comptime_float),
- .noreturn_type => return Type.initTag(.noreturn),
- .anyframe_type => return Type.initTag(.@"anyframe"),
- .null_type => return Type.initTag(.@"null"),
- .undefined_type => return Type.initTag(.@"undefined"),
- .enum_literal_type => return Type.initTag(.enum_literal),
- .atomic_ordering_type => return Type.initTag(.atomic_ordering),
- .atomic_rmw_op_type => return Type.initTag(.atomic_rmw_op),
- .calling_convention_type => return Type.initTag(.calling_convention),
- .float_mode_type => return Type.initTag(.float_mode),
- .reduce_op_type => return Type.initTag(.reduce_op),
- .call_options_type => return Type.initTag(.call_options),
- .export_options_type => return Type.initTag(.export_options),
- .extern_options_type => return Type.initTag(.extern_options),
- .manyptr_u8_type => return Type.initTag(.manyptr_u8),
- .manyptr_const_u8_type => return Type.initTag(.manyptr_const_u8),
- .fn_noreturn_no_args_type => return Type.initTag(.fn_noreturn_no_args),
- .fn_void_no_args_type => return Type.initTag(.fn_void_no_args),
- .fn_naked_noreturn_no_args_type => return Type.initTag(.fn_naked_noreturn_no_args),
- .fn_ccc_void_no_args_type => return Type.initTag(.fn_ccc_void_no_args),
- .single_const_pointer_to_comptime_int_type => return Type.initTag(.single_const_pointer_to_comptime_int),
- .const_slice_u8_type => return Type.initTag(.const_slice_u8),
- else => {},
+fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type {
+ var i: usize = @enumToInt(inst);
+ if (i < Air.Inst.Ref.typed_value_map.len) {
+ return Air.Inst.Ref.typed_value_map[i].ty;
}
- const air_index = @as(usize, @enumToInt(air_ref)) - Air.Inst.Ref.typed_value_map.len;
- const air_tags = sema.air_instructions.items(.tag);
+ i -= Air.Inst.Ref.typed_value_map.len;
+
const air_datas = sema.air_instructions.items(.data);
- assert(air_tags[air_index] == .const_ty);
- return air_datas[air_index].ty;
+ switch (sema.air_instructions.items(.tag)[i]) {
+ .arg => return sema.analyzeAsTypeInfallible(air_datas[i].ty_str.ty),
+
+ .add,
+ .addwrap,
+ .sub,
+ .subwrap,
+ .mul,
+ .mulwrap,
+ .div,
+ .bit_and,
+ .bit_or,
+ .xor,
+ => return sema.typeOf(air_datas[i].bin_op.lhs),
+
+ .cmp_lt,
+ .cmp_lte,
+ .cmp_eq,
+ .cmp_gte,
+ .cmp_gt,
+ .cmp_neq,
+ .is_null,
+ .is_non_null,
+ .is_null_ptr,
+ .is_non_null_ptr,
+ .is_err,
+ .is_non_err,
+ .is_err_ptr,
+ .is_non_err_ptr,
+ .bool_and,
+ .bool_or,
+ => return Type.initTag(.bool),
+
+ .const_ty => return Type.initTag(.type),
+
+ .alloc => return air_datas[i].ty,
+
+ .assembly,
+ .block,
+ .constant,
+ .varptr,
+ .struct_field_ptr,
+ => return sema.analyzeAsTypeInfallible(air_datas[i].ty_pl.ty),
+
+ .not,
+ .bitcast,
+ .load,
+ .ref,
+ .floatcast,
+ .intcast,
+ .optional_payload,
+ .optional_payload_ptr,
+ .wrap_optional,
+ .unwrap_errunion_payload,
+ .unwrap_errunion_err,
+ .unwrap_errunion_payload_ptr,
+ .unwrap_errunion_err_ptr,
+ .wrap_errunion_payload,
+ .wrap_errunion_err,
+ => return sema.analyzeAsTypeInfallible(air_datas[i].ty_op.ty),
+
+ .loop,
+ .br,
+ .cond_br,
+ .switch_br,
+ .ret,
+ .unreach,
+ => return Type.initTag(.noreturn),
+
+ .breakpoint,
+ .dbg_stmt,
+ .store,
+ => return Type.initTag(.void),
+
+ .ptrtoint => return Type.initTag(.usize),
+
+ .call => @panic("TODO Sema.typeOf call"),
+ }
}
pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {