mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 00:08:56 +00:00
Sema: finish reworking for AIR memory layout except switch
This commit is contained in:
parent
0da6633909
commit
12c10139e3
611
src/Sema.zig
611
src/Sema.zig
@ -276,101 +276,101 @@ pub fn analyzeBody(
|
||||
//.switch_capture_multi_ref => try sema.zirSwitchCapture(block, inst, true, true),
|
||||
//.switch_capture_else => try sema.zirSwitchCaptureElse(block, inst, false),
|
||||
//.switch_capture_else_ref => try sema.zirSwitchCaptureElse(block, inst, true),
|
||||
//.type_info => try sema.zirTypeInfo(block, inst),
|
||||
//.size_of => try sema.zirSizeOf(block, inst),
|
||||
//.bit_size_of => try sema.zirBitSizeOf(block, inst),
|
||||
//.typeof => try sema.zirTypeof(block, inst),
|
||||
//.typeof_elem => try sema.zirTypeofElem(block, inst),
|
||||
//.log2_int_type => try sema.zirLog2IntType(block, inst),
|
||||
//.typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst),
|
||||
//.xor => try sema.zirBitwise(block, inst, .xor),
|
||||
//.struct_init_empty => try sema.zirStructInitEmpty(block, inst),
|
||||
//.struct_init => try sema.zirStructInit(block, inst, false),
|
||||
//.struct_init_ref => try sema.zirStructInit(block, inst, true),
|
||||
//.struct_init_anon => try sema.zirStructInitAnon(block, inst, false),
|
||||
//.struct_init_anon_ref => try sema.zirStructInitAnon(block, inst, true),
|
||||
//.array_init => try sema.zirArrayInit(block, inst, false),
|
||||
//.array_init_ref => try sema.zirArrayInit(block, inst, true),
|
||||
//.array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
|
||||
//.array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true),
|
||||
//.union_init_ptr => try sema.zirUnionInitPtr(block, inst),
|
||||
//.field_type => try sema.zirFieldType(block, inst),
|
||||
//.field_type_ref => try sema.zirFieldTypeRef(block, inst),
|
||||
//.ptr_to_int => try sema.zirPtrToInt(block, inst),
|
||||
//.align_of => try sema.zirAlignOf(block, inst),
|
||||
//.bool_to_int => try sema.zirBoolToInt(block, inst),
|
||||
//.embed_file => try sema.zirEmbedFile(block, inst),
|
||||
//.error_name => try sema.zirErrorName(block, inst),
|
||||
//.tag_name => try sema.zirTagName(block, inst),
|
||||
//.reify => try sema.zirReify(block, inst),
|
||||
//.type_name => try sema.zirTypeName(block, inst),
|
||||
//.frame_type => try sema.zirFrameType(block, inst),
|
||||
//.frame_size => try sema.zirFrameSize(block, inst),
|
||||
//.float_to_int => try sema.zirFloatToInt(block, inst),
|
||||
//.int_to_float => try sema.zirIntToFloat(block, inst),
|
||||
//.int_to_ptr => try sema.zirIntToPtr(block, inst),
|
||||
//.float_cast => try sema.zirFloatCast(block, inst),
|
||||
//.int_cast => try sema.zirIntCast(block, inst),
|
||||
//.err_set_cast => try sema.zirErrSetCast(block, inst),
|
||||
//.ptr_cast => try sema.zirPtrCast(block, inst),
|
||||
//.truncate => try sema.zirTruncate(block, inst),
|
||||
//.align_cast => try sema.zirAlignCast(block, inst),
|
||||
//.has_decl => try sema.zirHasDecl(block, inst),
|
||||
//.has_field => try sema.zirHasField(block, inst),
|
||||
//.clz => try sema.zirClz(block, inst),
|
||||
//.ctz => try sema.zirCtz(block, inst),
|
||||
//.pop_count => try sema.zirPopCount(block, inst),
|
||||
//.byte_swap => try sema.zirByteSwap(block, inst),
|
||||
//.bit_reverse => try sema.zirBitReverse(block, inst),
|
||||
//.div_exact => try sema.zirDivExact(block, inst),
|
||||
//.div_floor => try sema.zirDivFloor(block, inst),
|
||||
//.div_trunc => try sema.zirDivTrunc(block, inst),
|
||||
//.mod => try sema.zirMod(block, inst),
|
||||
//.rem => try sema.zirRem(block, inst),
|
||||
//.shl_exact => try sema.zirShlExact(block, inst),
|
||||
//.shr_exact => try sema.zirShrExact(block, inst),
|
||||
//.bit_offset_of => try sema.zirBitOffsetOf(block, inst),
|
||||
//.offset_of => try sema.zirOffsetOf(block, inst),
|
||||
//.cmpxchg_strong => try sema.zirCmpxchg(block, inst),
|
||||
//.cmpxchg_weak => try sema.zirCmpxchg(block, inst),
|
||||
//.splat => try sema.zirSplat(block, inst),
|
||||
//.reduce => try sema.zirReduce(block, inst),
|
||||
//.shuffle => try sema.zirShuffle(block, inst),
|
||||
//.atomic_load => try sema.zirAtomicLoad(block, inst),
|
||||
//.atomic_rmw => try sema.zirAtomicRmw(block, inst),
|
||||
//.atomic_store => try sema.zirAtomicStore(block, inst),
|
||||
//.mul_add => try sema.zirMulAdd(block, inst),
|
||||
//.builtin_call => try sema.zirBuiltinCall(block, inst),
|
||||
//.field_ptr_type => try sema.zirFieldPtrType(block, inst),
|
||||
//.field_parent_ptr => try sema.zirFieldParentPtr(block, inst),
|
||||
//.memcpy => try sema.zirMemcpy(block, inst),
|
||||
//.memset => try sema.zirMemset(block, inst),
|
||||
//.builtin_async_call => try sema.zirBuiltinAsyncCall(block, inst),
|
||||
//.@"resume" => try sema.zirResume(block, inst),
|
||||
//.@"await" => try sema.zirAwait(block, inst, false),
|
||||
//.await_nosuspend => try sema.zirAwait(block, inst, true),
|
||||
//.extended => try sema.zirExtended(block, inst),
|
||||
.type_info => try sema.zirTypeInfo(block, inst),
|
||||
.size_of => try sema.zirSizeOf(block, inst),
|
||||
.bit_size_of => try sema.zirBitSizeOf(block, inst),
|
||||
.typeof => try sema.zirTypeof(block, inst),
|
||||
.typeof_elem => try sema.zirTypeofElem(block, inst),
|
||||
.log2_int_type => try sema.zirLog2IntType(block, inst),
|
||||
.typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst),
|
||||
.xor => try sema.zirBitwise(block, inst, .xor),
|
||||
.struct_init_empty => try sema.zirStructInitEmpty(block, inst),
|
||||
.struct_init => try sema.zirStructInit(block, inst, false),
|
||||
.struct_init_ref => try sema.zirStructInit(block, inst, true),
|
||||
.struct_init_anon => try sema.zirStructInitAnon(block, inst, false),
|
||||
.struct_init_anon_ref => try sema.zirStructInitAnon(block, inst, true),
|
||||
.array_init => try sema.zirArrayInit(block, inst, false),
|
||||
.array_init_ref => try sema.zirArrayInit(block, inst, true),
|
||||
.array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
|
||||
.array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true),
|
||||
.union_init_ptr => try sema.zirUnionInitPtr(block, inst),
|
||||
.field_type => try sema.zirFieldType(block, inst),
|
||||
.field_type_ref => try sema.zirFieldTypeRef(block, inst),
|
||||
.ptr_to_int => try sema.zirPtrToInt(block, inst),
|
||||
.align_of => try sema.zirAlignOf(block, inst),
|
||||
.bool_to_int => try sema.zirBoolToInt(block, inst),
|
||||
.embed_file => try sema.zirEmbedFile(block, inst),
|
||||
.error_name => try sema.zirErrorName(block, inst),
|
||||
.tag_name => try sema.zirTagName(block, inst),
|
||||
.reify => try sema.zirReify(block, inst),
|
||||
.type_name => try sema.zirTypeName(block, inst),
|
||||
.frame_type => try sema.zirFrameType(block, inst),
|
||||
.frame_size => try sema.zirFrameSize(block, inst),
|
||||
.float_to_int => try sema.zirFloatToInt(block, inst),
|
||||
.int_to_float => try sema.zirIntToFloat(block, inst),
|
||||
.int_to_ptr => try sema.zirIntToPtr(block, inst),
|
||||
.float_cast => try sema.zirFloatCast(block, inst),
|
||||
.int_cast => try sema.zirIntCast(block, inst),
|
||||
.err_set_cast => try sema.zirErrSetCast(block, inst),
|
||||
.ptr_cast => try sema.zirPtrCast(block, inst),
|
||||
.truncate => try sema.zirTruncate(block, inst),
|
||||
.align_cast => try sema.zirAlignCast(block, inst),
|
||||
.has_decl => try sema.zirHasDecl(block, inst),
|
||||
.has_field => try sema.zirHasField(block, inst),
|
||||
.clz => try sema.zirClz(block, inst),
|
||||
.ctz => try sema.zirCtz(block, inst),
|
||||
.pop_count => try sema.zirPopCount(block, inst),
|
||||
.byte_swap => try sema.zirByteSwap(block, inst),
|
||||
.bit_reverse => try sema.zirBitReverse(block, inst),
|
||||
.div_exact => try sema.zirDivExact(block, inst),
|
||||
.div_floor => try sema.zirDivFloor(block, inst),
|
||||
.div_trunc => try sema.zirDivTrunc(block, inst),
|
||||
.mod => try sema.zirMod(block, inst),
|
||||
.rem => try sema.zirRem(block, inst),
|
||||
.shl_exact => try sema.zirShlExact(block, inst),
|
||||
.shr_exact => try sema.zirShrExact(block, inst),
|
||||
.bit_offset_of => try sema.zirBitOffsetOf(block, inst),
|
||||
.offset_of => try sema.zirOffsetOf(block, inst),
|
||||
.cmpxchg_strong => try sema.zirCmpxchg(block, inst),
|
||||
.cmpxchg_weak => try sema.zirCmpxchg(block, inst),
|
||||
.splat => try sema.zirSplat(block, inst),
|
||||
.reduce => try sema.zirReduce(block, inst),
|
||||
.shuffle => try sema.zirShuffle(block, inst),
|
||||
.atomic_load => try sema.zirAtomicLoad(block, inst),
|
||||
.atomic_rmw => try sema.zirAtomicRmw(block, inst),
|
||||
.atomic_store => try sema.zirAtomicStore(block, inst),
|
||||
.mul_add => try sema.zirMulAdd(block, inst),
|
||||
.builtin_call => try sema.zirBuiltinCall(block, inst),
|
||||
.field_ptr_type => try sema.zirFieldPtrType(block, inst),
|
||||
.field_parent_ptr => try sema.zirFieldParentPtr(block, inst),
|
||||
.memcpy => try sema.zirMemcpy(block, inst),
|
||||
.memset => try sema.zirMemset(block, inst),
|
||||
.builtin_async_call => try sema.zirBuiltinAsyncCall(block, inst),
|
||||
.@"resume" => try sema.zirResume(block, inst),
|
||||
.@"await" => try sema.zirAwait(block, inst, false),
|
||||
.await_nosuspend => try sema.zirAwait(block, inst, true),
|
||||
.extended => try sema.zirExtended(block, inst),
|
||||
|
||||
//.sqrt => try sema.zirUnaryMath(block, inst),
|
||||
//.sin => try sema.zirUnaryMath(block, inst),
|
||||
//.cos => try sema.zirUnaryMath(block, inst),
|
||||
//.exp => try sema.zirUnaryMath(block, inst),
|
||||
//.exp2 => try sema.zirUnaryMath(block, inst),
|
||||
//.log => try sema.zirUnaryMath(block, inst),
|
||||
//.log2 => try sema.zirUnaryMath(block, inst),
|
||||
//.log10 => try sema.zirUnaryMath(block, inst),
|
||||
//.fabs => try sema.zirUnaryMath(block, inst),
|
||||
//.floor => try sema.zirUnaryMath(block, inst),
|
||||
//.ceil => try sema.zirUnaryMath(block, inst),
|
||||
//.trunc => try sema.zirUnaryMath(block, inst),
|
||||
//.round => try sema.zirUnaryMath(block, inst),
|
||||
.sqrt => try sema.zirUnaryMath(block, inst),
|
||||
.sin => try sema.zirUnaryMath(block, inst),
|
||||
.cos => try sema.zirUnaryMath(block, inst),
|
||||
.exp => try sema.zirUnaryMath(block, inst),
|
||||
.exp2 => try sema.zirUnaryMath(block, inst),
|
||||
.log => try sema.zirUnaryMath(block, inst),
|
||||
.log2 => try sema.zirUnaryMath(block, inst),
|
||||
.log10 => try sema.zirUnaryMath(block, inst),
|
||||
.fabs => try sema.zirUnaryMath(block, inst),
|
||||
.floor => try sema.zirUnaryMath(block, inst),
|
||||
.ceil => try sema.zirUnaryMath(block, inst),
|
||||
.trunc => try sema.zirUnaryMath(block, inst),
|
||||
.round => try sema.zirUnaryMath(block, inst),
|
||||
|
||||
//.opaque_decl => try sema.zirOpaqueDecl(block, inst, .parent),
|
||||
//.opaque_decl_anon => try sema.zirOpaqueDecl(block, inst, .anon),
|
||||
//.opaque_decl_func => try sema.zirOpaqueDecl(block, inst, .func),
|
||||
//.error_set_decl => try sema.zirErrorSetDecl(block, inst, .parent),
|
||||
//.error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),
|
||||
//.error_set_decl_func => try sema.zirErrorSetDecl(block, inst, .func),
|
||||
.opaque_decl => try sema.zirOpaqueDecl(block, inst, .parent),
|
||||
.opaque_decl_anon => try sema.zirOpaqueDecl(block, inst, .anon),
|
||||
.opaque_decl_func => try sema.zirOpaqueDecl(block, inst, .func),
|
||||
.error_set_decl => try sema.zirErrorSetDecl(block, inst, .parent),
|
||||
.error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),
|
||||
.error_set_decl_func => try sema.zirErrorSetDecl(block, inst, .func),
|
||||
|
||||
.add => try sema.zirArithmetic(block, inst),
|
||||
.addwrap => try sema.zirArithmetic(block, inst),
|
||||
@ -396,106 +396,106 @@ pub fn analyzeBody(
|
||||
.panic => return sema.zirPanic(block, inst),
|
||||
// zig fmt: on
|
||||
|
||||
//// Instructions that we know can *never* be noreturn based solely on
|
||||
//// their tag. We avoid needlessly checking if they are noreturn and
|
||||
//// continue the loop.
|
||||
//// We also know that they cannot be referenced later, so we avoid
|
||||
//// putting them into the map.
|
||||
//.breakpoint => {
|
||||
// try sema.zirBreakpoint(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.fence => {
|
||||
// try sema.zirFence(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.dbg_stmt => {
|
||||
// try sema.zirDbgStmt(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.ensure_err_payload_void => {
|
||||
// try sema.zirEnsureErrPayloadVoid(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.ensure_result_non_error => {
|
||||
// try sema.zirEnsureResultNonError(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.ensure_result_used => {
|
||||
// try sema.zirEnsureResultUsed(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.set_eval_branch_quota => {
|
||||
// try sema.zirSetEvalBranchQuota(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.store => {
|
||||
// try sema.zirStore(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.store_node => {
|
||||
// try sema.zirStoreNode(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.store_to_block_ptr => {
|
||||
// try sema.zirStoreToBlockPtr(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.store_to_inferred_ptr => {
|
||||
// try sema.zirStoreToInferredPtr(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.resolve_inferred_alloc => {
|
||||
// try sema.zirResolveInferredAlloc(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.validate_struct_init_ptr => {
|
||||
// try sema.zirValidateStructInitPtr(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.validate_array_init_ptr => {
|
||||
// try sema.zirValidateArrayInitPtr(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.@"export" => {
|
||||
// try sema.zirExport(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.set_align_stack => {
|
||||
// try sema.zirSetAlignStack(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.set_cold => {
|
||||
// try sema.zirSetCold(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.set_float_mode => {
|
||||
// try sema.zirSetFloatMode(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
//.set_runtime_safety => {
|
||||
// try sema.zirSetRuntimeSafety(block, inst);
|
||||
// i += 1;
|
||||
// continue;
|
||||
//},
|
||||
// Instructions that we know can *never* be noreturn based solely on
|
||||
// their tag. We avoid needlessly checking if they are noreturn and
|
||||
// continue the loop.
|
||||
// We also know that they cannot be referenced later, so we avoid
|
||||
// putting them into the map.
|
||||
.breakpoint => {
|
||||
try sema.zirBreakpoint(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.fence => {
|
||||
try sema.zirFence(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.dbg_stmt => {
|
||||
try sema.zirDbgStmt(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.ensure_err_payload_void => {
|
||||
try sema.zirEnsureErrPayloadVoid(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.ensure_result_non_error => {
|
||||
try sema.zirEnsureResultNonError(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.ensure_result_used => {
|
||||
try sema.zirEnsureResultUsed(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.set_eval_branch_quota => {
|
||||
try sema.zirSetEvalBranchQuota(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.store => {
|
||||
try sema.zirStore(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.store_node => {
|
||||
try sema.zirStoreNode(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.store_to_block_ptr => {
|
||||
try sema.zirStoreToBlockPtr(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.store_to_inferred_ptr => {
|
||||
try sema.zirStoreToInferredPtr(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.resolve_inferred_alloc => {
|
||||
try sema.zirResolveInferredAlloc(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.validate_struct_init_ptr => {
|
||||
try sema.zirValidateStructInitPtr(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.validate_array_init_ptr => {
|
||||
try sema.zirValidateArrayInitPtr(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.@"export" => {
|
||||
try sema.zirExport(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.set_align_stack => {
|
||||
try sema.zirSetAlignStack(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.set_cold => {
|
||||
try sema.zirSetCold(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.set_float_mode => {
|
||||
try sema.zirSetFloatMode(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.set_runtime_safety => {
|
||||
try sema.zirSetRuntimeSafety(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
|
||||
// Special case instructions to handle comptime control flow.
|
||||
.repeat_inline => {
|
||||
@ -562,7 +562,7 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
|
||||
.frame_address => return sema.zirFrameAddress( block, extended),
|
||||
.alloc => return sema.zirAllocExtended( block, extended),
|
||||
.builtin_extern => return sema.zirBuiltinExtern( block, extended),
|
||||
.@"asm" => return sema.zirAsm( block, extended),
|
||||
.@"asm" => return sema.zirAsm( block, extended, inst),
|
||||
.typeof_peer => return sema.zirTypeofPeer( block, extended),
|
||||
.compile_log => return sema.zirCompileLog( block, extended),
|
||||
.add_with_overflow => return sema.zirOverflowArithmetic(block, extended),
|
||||
@ -1400,11 +1400,14 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
|
||||
const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
|
||||
const ptr = sema.resolveInst(inst_data.operand);
|
||||
const ptr_val = ptr.castTag(.constant).?.val;
|
||||
const ptr_inst = refToIndex(ptr).?;
|
||||
assert(sema.air_instructions.items(.tag)[ptr_inst] == .constant);
|
||||
const air_datas = sema.air_instructions.items(.data);
|
||||
const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload];
|
||||
const inferred_alloc = ptr_val.castTag(.inferred_alloc).?;
|
||||
const peer_inst_list = inferred_alloc.data.stored_inst_list.items;
|
||||
const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list);
|
||||
const var_is_mut = switch (ptr.ty.tag()) {
|
||||
const var_is_mut = switch (sema.typeOf(ptr).tag()) {
|
||||
.inferred_alloc_const => false,
|
||||
.inferred_alloc_mut => true,
|
||||
else => unreachable,
|
||||
@ -1415,8 +1418,10 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde
|
||||
const final_ptr_ty = try Module.simplePtrType(sema.arena, final_elem_ty, true, .One);
|
||||
|
||||
// Change it to a normal alloc.
|
||||
ptr.ty = final_ptr_ty;
|
||||
ptr.tag = .alloc;
|
||||
sema.air_instructions.set(ptr_inst, .{
|
||||
.tag = .alloc,
|
||||
.data = .{ .ty = final_ptr_ty },
|
||||
});
|
||||
}
|
||||
|
||||
fn zirValidateStructInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {
|
||||
@ -1434,7 +1439,7 @@ fn zirValidateStructInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Ind
|
||||
const field_ptr_data = sema.code.instructions.items(.data)[instrs[0]].pl_node;
|
||||
const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
|
||||
const object_ptr = sema.resolveInst(field_ptr_extra.lhs);
|
||||
break :s object_ptr.ty.elemType().castTag(.@"struct").?.data;
|
||||
break :s sema.typeOf(object_ptr).elemType().castTag(.@"struct").?.data;
|
||||
};
|
||||
|
||||
// Maps field index to field_ptr index of where it was already initialized.
|
||||
@ -1564,7 +1569,7 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co
|
||||
}
|
||||
const ptr = sema.resolveInst(bin_inst.lhs);
|
||||
const value = sema.resolveInst(bin_inst.rhs);
|
||||
const ptr_ty = try Module.simplePtrType(sema.arena, value.ty, true, .One);
|
||||
const ptr_ty = try Module.simplePtrType(sema.arena, sema.typeOf(value), true, .One);
|
||||
// TODO detect when this store should be done at compile-time. For example,
|
||||
// if expressions should force it when the condition is compile-time known.
|
||||
const src: LazySrcLoc = .unneeded;
|
||||
@ -1581,12 +1586,16 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)
|
||||
const bin_inst = sema.code.instructions.items(.data)[inst].bin;
|
||||
const ptr = sema.resolveInst(bin_inst.lhs);
|
||||
const value = sema.resolveInst(bin_inst.rhs);
|
||||
const inferred_alloc = ptr.castTag(.constant).?.val.castTag(.inferred_alloc).?;
|
||||
const ptr_inst = refToIndex(ptr).?;
|
||||
assert(sema.air_instructions.items(.tag)[ptr_inst] == .constant);
|
||||
const air_datas = sema.air_instructions.items(.data);
|
||||
const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload];
|
||||
const inferred_alloc = ptr_val.castTag(.inferred_alloc).?;
|
||||
// Add the stored instruction to the set we will use to resolve peer types
|
||||
// for the inferred allocation.
|
||||
try inferred_alloc.data.stored_inst_list.append(sema.arena, value);
|
||||
// Create a runtime bitcast instruction with exactly the type the pointer wants.
|
||||
const ptr_ty = try Module.simplePtrType(sema.arena, value.ty, true, .One);
|
||||
const ptr_ty = try Module.simplePtrType(sema.arena, sema.typeOf(value), true, .One);
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr);
|
||||
return sema.storePtr(block, src, bitcasted_ptr, value);
|
||||
@ -1767,10 +1776,11 @@ fn zirCompileLog(
|
||||
if (i != 0) try writer.print(", ", .{});
|
||||
|
||||
const arg = sema.resolveInst(arg_ref);
|
||||
const arg_ty = sema.typeOf(arg);
|
||||
if (try sema.resolvePossiblyUndefinedValue(block, src, arg)) |val| {
|
||||
try writer.print("@as({}, {})", .{ arg.ty, val });
|
||||
try writer.print("@as({}, {})", .{ arg_ty, val });
|
||||
} else {
|
||||
try writer.print("@as({}, [runtime value])", .{arg.ty});
|
||||
try writer.print("@as({}, [runtime value])", .{arg_ty});
|
||||
}
|
||||
}
|
||||
try writer.print("\n", .{});
|
||||
@ -2157,7 +2167,13 @@ fn zirDbgStmt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
|
||||
if (block.is_comptime) return;
|
||||
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].dbg_stmt;
|
||||
_ = try block.addDbgStmt(.unneeded, inst_data.line, inst_data.column);
|
||||
_ = try block.addInst(.{
|
||||
.tag = .dbg_stmt,
|
||||
.data = .{ .dbg_stmt = .{
|
||||
.line = inst_data.line,
|
||||
.column = inst_data.column,
|
||||
} },
|
||||
});
|
||||
}
|
||||
|
||||
fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
@ -3263,9 +3279,10 @@ fn zirPtrToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
|
||||
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
|
||||
const ptr = sema.resolveInst(inst_data.operand);
|
||||
if (ptr.ty.zigTypeTag() != .Pointer) {
|
||||
const ptr_ty = sema.typeOf(ptr);
|
||||
if (ptr_ty.zigTypeTag() != .Pointer) {
|
||||
const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
|
||||
return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr.ty});
|
||||
return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr_ty});
|
||||
}
|
||||
// TODO handle known-pointer-address
|
||||
const src = inst_data.src();
|
||||
@ -3368,7 +3385,7 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
|
||||
),
|
||||
}
|
||||
|
||||
if (operand.value() != null) {
|
||||
if (try sema.isComptimeKnown(block, operand_src, operand)) {
|
||||
return sema.coerce(block, dest_type, operand, operand_src);
|
||||
} else if (dest_is_comptime_int) {
|
||||
return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_int'", .{});
|
||||
@ -3426,7 +3443,7 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
|
||||
),
|
||||
}
|
||||
|
||||
if (operand.value() != null) {
|
||||
if (try sema.isComptimeKnown(block, operand_src, operand)) {
|
||||
return sema.coerce(block, dest_type, operand, operand_src);
|
||||
} else if (dest_is_comptime_float) {
|
||||
return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_float'", .{});
|
||||
@ -4843,19 +4860,17 @@ fn zirAsm(
|
||||
sema: *Sema,
|
||||
block: *Scope.Block,
|
||||
extended: Zir.Inst.Extended.InstData,
|
||||
inst: Zir.Inst.Index,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand);
|
||||
const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
|
||||
const asm_source_src: LazySrcLoc = .{ .node_offset_asm_source = extra.data.src_node };
|
||||
const ret_ty_src: LazySrcLoc = .{ .node_offset_asm_ret_ty = extra.data.src_node };
|
||||
const asm_source = try sema.resolveConstString(block, asm_source_src, extra.data.asm_source);
|
||||
const outputs_len = @truncate(u5, extended.small);
|
||||
const inputs_len = @truncate(u5, extended.small >> 5);
|
||||
const clobbers_len = @truncate(u5, extended.small >> 10);
|
||||
const is_volatile = @truncate(u1, extended.small >> 15) != 0;
|
||||
|
||||
if (outputs_len > 1) {
|
||||
return sema.mod.fail(&block.base, src, "TODO implement Sema for asm with more than 1 output", .{});
|
||||
@ -4883,7 +4898,7 @@ fn zirAsm(
|
||||
};
|
||||
};
|
||||
|
||||
const args = try sema.arena.alloc(Air.Inst.Index, inputs_len);
|
||||
const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);
|
||||
const inputs = try sema.arena.alloc([]const u8, inputs_len);
|
||||
|
||||
for (args) |*arg, arg_i| {
|
||||
@ -4904,22 +4919,19 @@ fn zirAsm(
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
const asm_air = try sema.arena.create(Inst.Assembly);
|
||||
asm_air.* = .{
|
||||
.base = .{
|
||||
.tag = .assembly,
|
||||
.ty = if (output) |o| o.ty else Type.initTag(.void),
|
||||
.src = src,
|
||||
},
|
||||
.asm_source = asm_source,
|
||||
.is_volatile = is_volatile,
|
||||
.output_constraint = if (output) |o| o.constraint else null,
|
||||
.inputs = inputs,
|
||||
.clobbers = clobbers,
|
||||
.args = args,
|
||||
};
|
||||
try block.instructions.append(sema.gpa, &asm_air.base);
|
||||
return &asm_air.base;
|
||||
const gpa = sema.gpa;
|
||||
try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Asm).Struct.fields.len + args.len);
|
||||
const asm_air = try block.addInst(.{
|
||||
.tag = .assembly,
|
||||
.data = .{ .ty_pl = .{
|
||||
.ty = if (output) |o| try sema.addType(o.ty) else Air.Inst.Ref.void_type,
|
||||
.payload = sema.addExtraAssumeCapacity(Air.Asm{
|
||||
.zir_index = inst,
|
||||
}),
|
||||
} },
|
||||
});
|
||||
sema.appendRefsAssumeCapacity(args);
|
||||
return asm_air;
|
||||
}
|
||||
|
||||
fn zirCmp(
|
||||
@ -5153,7 +5165,7 @@ fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile
|
||||
_ = block;
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
|
||||
const operand_ptr = sema.resolveInst(inst_data.operand);
|
||||
const elem_ty = operand_ptr.ty.elemType();
|
||||
const elem_ty = sema.typeOf(operand_ptr).elemType();
|
||||
return sema.addType(elem_ty);
|
||||
}
|
||||
|
||||
@ -5181,7 +5193,7 @@ fn zirTypeofPeer(
|
||||
const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
|
||||
const args = sema.code.refSlice(extra.end, extended.small);
|
||||
|
||||
const inst_list = try sema.gpa.alloc(Air.Inst.Index, args.len);
|
||||
const inst_list = try sema.gpa.alloc(Air.Inst.Ref, args.len);
|
||||
defer sema.gpa.free(inst_list);
|
||||
|
||||
for (args) |arg_ref, i| {
|
||||
@ -5623,7 +5635,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref:
|
||||
mem.set(Zir.Inst.Index, found_fields, 0);
|
||||
|
||||
// The init values to use for the struct instance.
|
||||
const field_inits = try gpa.alloc(Air.Inst.Index, struct_obj.fields.count());
|
||||
const field_inits = try gpa.alloc(Air.Inst.Ref, struct_obj.fields.count());
|
||||
defer gpa.free(field_inits);
|
||||
|
||||
var field_i: u32 = 0;
|
||||
@ -5692,7 +5704,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref:
|
||||
}
|
||||
|
||||
const is_comptime = for (field_inits) |field_init| {
|
||||
if (field_init.value() == null) {
|
||||
if (!(try sema.isComptimeKnown(block, src, field_init))) {
|
||||
break false;
|
||||
}
|
||||
} else true;
|
||||
@ -5700,7 +5712,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref:
|
||||
if (is_comptime) {
|
||||
const values = try sema.arena.alloc(Value, field_inits.len);
|
||||
for (field_inits) |field_init, i| {
|
||||
values[i] = field_init.value().?;
|
||||
values[i] = (sema.resolvePossiblyUndefinedValue(block, src, field_init) catch unreachable).?;
|
||||
}
|
||||
return sema.addConstant(struct_ty, try Value.Tag.@"struct".create(sema.arena, values.ptr));
|
||||
}
|
||||
@ -6835,17 +6847,13 @@ fn coerce(
|
||||
}
|
||||
assert(inst_ty.zigTypeTag() != .Undefined);
|
||||
|
||||
if (true) {
|
||||
@panic("TODO finish AIR memory layout rework");
|
||||
}
|
||||
|
||||
// T to E!T or E to E!T
|
||||
if (dest_type.tag() == .error_union) {
|
||||
return try sema.wrapErrorUnion(block, dest_type, inst, inst_src);
|
||||
}
|
||||
|
||||
// comptime known number to other number
|
||||
if (try sema.coerceNum(block, dest_type, inst)) |some|
|
||||
if (try sema.coerceNum(block, dest_type, inst, inst_src)) |some|
|
||||
return some;
|
||||
|
||||
const target = mod.getTarget();
|
||||
@ -6861,9 +6869,9 @@ fn coerce(
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
const child_type = dest_type.optionalChild(&buf);
|
||||
if (child_type.eql(inst_ty)) {
|
||||
return sema.wrapOptional(block, dest_type, inst);
|
||||
} else if (try sema.coerceNum(block, child_type, inst)) |some| {
|
||||
return sema.wrapOptional(block, dest_type, some);
|
||||
return sema.wrapOptional(block, dest_type, inst, inst_src);
|
||||
} else if (try sema.coerceNum(block, child_type, inst, inst_src)) |some| {
|
||||
return sema.wrapOptional(block, dest_type, some, inst_src);
|
||||
}
|
||||
},
|
||||
.Pointer => {
|
||||
@ -6885,11 +6893,11 @@ fn coerce(
|
||||
switch (dest_type.ptrSize()) {
|
||||
.Slice => {
|
||||
// *[N]T to []T
|
||||
return sema.coerceArrayPtrToSlice(block, dest_type, inst);
|
||||
return sema.coerceArrayPtrToSlice(block, dest_type, inst, inst_src);
|
||||
},
|
||||
.C => {
|
||||
// *[N]T to [*c]T
|
||||
return sema.coerceArrayPtrToMany(block, dest_type, inst);
|
||||
return sema.coerceArrayPtrToMany(block, dest_type, inst, inst_src);
|
||||
},
|
||||
.Many => {
|
||||
// *[N]T to [*]T
|
||||
@ -6897,12 +6905,12 @@ fn coerce(
|
||||
const src_sentinel = array_type.sentinel();
|
||||
const dst_sentinel = dest_type.sentinel();
|
||||
if (src_sentinel == null and dst_sentinel == null)
|
||||
return sema.coerceArrayPtrToMany(block, dest_type, inst);
|
||||
return sema.coerceArrayPtrToMany(block, dest_type, inst, inst_src);
|
||||
|
||||
if (src_sentinel) |src_s| {
|
||||
if (dst_sentinel) |dst_s| {
|
||||
if (src_s.eql(dst_s)) {
|
||||
return sema.coerceArrayPtrToMany(block, dest_type, inst);
|
||||
return sema.coerceArrayPtrToMany(block, dest_type, inst, inst_src);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6914,7 +6922,7 @@ fn coerce(
|
||||
.Int => {
|
||||
// integer widening
|
||||
if (inst_ty.zigTypeTag() == .Int) {
|
||||
assert(inst.value() == null); // handled above
|
||||
assert(!(try sema.isComptimeKnown(block, inst_src, inst))); // handled above
|
||||
|
||||
const dst_info = dest_type.intInfo(target);
|
||||
const src_info = inst_ty.intInfo(target);
|
||||
@ -6930,7 +6938,7 @@ fn coerce(
|
||||
.Float => {
|
||||
// float widening
|
||||
if (inst_ty.zigTypeTag() == .Float) {
|
||||
assert(inst.value() == null); // handled above
|
||||
assert(!(try sema.isComptimeKnown(block, inst_src, inst))); // handled above
|
||||
|
||||
const src_bits = inst_ty.floatBits(target);
|
||||
const dst_bits = dest_type.floatBits(target);
|
||||
@ -6991,9 +6999,16 @@ fn coerceInMemoryAllowed(dest_type: Type, src_type: Type) InMemoryCoercionResult
|
||||
return .no_match;
|
||||
}
|
||||
|
||||
fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) CompileError!?Air.Inst.Index {
|
||||
const val = inst.value() orelse return null;
|
||||
const src_zig_tag = inst.ty.zigTypeTag();
|
||||
fn coerceNum(
|
||||
sema: *Sema,
|
||||
block: *Scope.Block,
|
||||
dest_type: Type,
|
||||
inst: Air.Inst.Ref,
|
||||
inst_src: LazySrcLoc,
|
||||
) CompileError!?Air.Inst.Ref {
|
||||
const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse return null;
|
||||
const inst_ty = sema.typeOf(inst);
|
||||
const src_zig_tag = inst_ty.zigTypeTag();
|
||||
const dst_zig_tag = dest_type.zigTypeTag();
|
||||
|
||||
const target = sema.mod.getTarget();
|
||||
@ -7001,29 +7016,29 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.R
|
||||
if (dst_zig_tag == .ComptimeInt or dst_zig_tag == .Int) {
|
||||
if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) {
|
||||
if (val.floatHasFraction()) {
|
||||
return sema.mod.fail(&block.base, inst.src, "fractional component prevents float value {} from being casted to type '{}'", .{ val, inst.ty });
|
||||
return sema.mod.fail(&block.base, inst_src, "fractional component prevents float value {} from being casted to type '{}'", .{ val, inst_ty });
|
||||
}
|
||||
return sema.mod.fail(&block.base, inst.src, "TODO float to int", .{});
|
||||
return sema.mod.fail(&block.base, inst_src, "TODO float to int", .{});
|
||||
} else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) {
|
||||
if (!val.intFitsInType(dest_type, target)) {
|
||||
return sema.mod.fail(&block.base, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val });
|
||||
return sema.mod.fail(&block.base, inst_src, "type {} cannot represent integer value {}", .{ inst_ty, val });
|
||||
}
|
||||
return sema.addConstant(dest_type, val);
|
||||
return try sema.addConstant(dest_type, val);
|
||||
}
|
||||
} else if (dst_zig_tag == .ComptimeFloat or dst_zig_tag == .Float) {
|
||||
if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) {
|
||||
const res = val.floatCast(sema.arena, dest_type, target) catch |err| switch (err) {
|
||||
error.Overflow => return sema.mod.fail(
|
||||
&block.base,
|
||||
inst.src,
|
||||
inst_src,
|
||||
"cast of value {} to type '{}' loses information",
|
||||
.{ val, dest_type },
|
||||
),
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
};
|
||||
return sema.addConstant(dest_type, res);
|
||||
return try sema.addConstant(dest_type, res);
|
||||
} else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) {
|
||||
return sema.mod.fail(&block.base, inst.src, "TODO int to float", .{});
|
||||
return sema.mod.fail(&block.base, inst_src, "TODO int to float", .{});
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -7051,10 +7066,11 @@ fn storePtr(
|
||||
ptr: Air.Inst.Ref,
|
||||
uncasted_value: Air.Inst.Ref,
|
||||
) !void {
|
||||
if (ptr.ty.isConstPtr())
|
||||
const ptr_ty = sema.typeOf(ptr);
|
||||
if (ptr_ty.isConstPtr())
|
||||
return sema.mod.fail(&block.base, src, "cannot assign to constant", .{});
|
||||
|
||||
const elem_ty = ptr.ty.elemType();
|
||||
const elem_ty = ptr_ty.elemType();
|
||||
const value = try sema.coerce(block, elem_ty, uncasted_value, src);
|
||||
if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null)
|
||||
return;
|
||||
@ -7113,20 +7129,32 @@ fn bitcast(
|
||||
return block.addTyOp(.bitcast, dest_type, inst);
|
||||
}
|
||||
|
||||
fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) CompileError!Air.Inst.Ref {
|
||||
if (inst.value()) |val| {
|
||||
fn coerceArrayPtrToSlice(
|
||||
sema: *Sema,
|
||||
block: *Scope.Block,
|
||||
dest_type: Type,
|
||||
inst: Air.Inst.Ref,
|
||||
inst_src: LazySrcLoc,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
|
||||
// The comptime Value representation is compatible with both types.
|
||||
return sema.addConstant(dest_type, val);
|
||||
}
|
||||
return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{});
|
||||
return sema.mod.fail(&block.base, inst_src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{});
|
||||
}
|
||||
|
||||
fn coerceArrayPtrToMany(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Ref {
|
||||
if (inst.value()) |val| {
|
||||
fn coerceArrayPtrToMany(
|
||||
sema: *Sema,
|
||||
block: *Scope.Block,
|
||||
dest_type: Type,
|
||||
inst: Air.Inst.Ref,
|
||||
inst_src: LazySrcLoc,
|
||||
) !Air.Inst.Ref {
|
||||
if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
|
||||
// The comptime Value representation is compatible with both types.
|
||||
return sema.addConstant(dest_type, val);
|
||||
}
|
||||
return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToMany runtime instruction", .{});
|
||||
return sema.mod.fail(&block.base, inst_src, "TODO implement coerceArrayPtrToMany runtime instruction", .{});
|
||||
}
|
||||
|
||||
fn analyzeDeclVal(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, decl: *Decl) CompileError!Air.Inst.Ref {
|
||||
@ -7531,12 +7559,18 @@ fn cmpNumeric(
|
||||
return block.addBinOp(Air.Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
|
||||
}
|
||||
|
||||
fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Index {
|
||||
fn wrapOptional(
|
||||
sema: *Sema,
|
||||
block: *Scope.Block,
|
||||
dest_type: Type,
|
||||
inst: Air.Inst.Ref,
|
||||
inst_src: LazySrcLoc,
|
||||
) !Air.Inst.Ref {
|
||||
if (try sema.resolvePossiblyUndefinedValue(block, inst_src, inst)) |val| {
|
||||
return sema.addConstant(dest_type, val);
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, inst.src);
|
||||
try sema.requireRuntimeBlock(block, inst_src);
|
||||
return block.addTyOp(.wrap_optional, dest_type, inst);
|
||||
}
|
||||
|
||||
@ -7546,11 +7580,12 @@ fn wrapErrorUnion(
|
||||
dest_type: Type,
|
||||
inst: Air.Inst.Ref,
|
||||
inst_src: LazySrcLoc,
|
||||
) !Air.Inst.Index {
|
||||
) !Air.Inst.Ref {
|
||||
const inst_ty = sema.typeOf(inst);
|
||||
const err_union = dest_type.castTag(.error_union).?;
|
||||
if (try sema.resolvePossiblyUndefinedValue(block, inst_src, inst)) |val| {
|
||||
if (inst.ty.zigTypeTag() != .ErrorSet) {
|
||||
_ = try sema.coerce(block, err_union.data.payload, inst, inst.src);
|
||||
if (inst_ty.zigTypeTag() != .ErrorSet) {
|
||||
_ = try sema.coerce(block, err_union.data.payload, inst, inst_src);
|
||||
} else switch (err_union.data.error_set.tag()) {
|
||||
.anyerror => {},
|
||||
.error_set_single => {
|
||||
@ -7559,9 +7594,9 @@ fn wrapErrorUnion(
|
||||
if (!mem.eql(u8, expected_name, n)) {
|
||||
return sema.mod.fail(
|
||||
&block.base,
|
||||
inst.src,
|
||||
inst_src,
|
||||
"expected type '{}', found type '{}'",
|
||||
.{ err_union.data.error_set, inst.ty },
|
||||
.{ err_union.data.error_set, inst_ty },
|
||||
);
|
||||
}
|
||||
},
|
||||
@ -7577,9 +7612,9 @@ fn wrapErrorUnion(
|
||||
if (!found) {
|
||||
return sema.mod.fail(
|
||||
&block.base,
|
||||
inst.src,
|
||||
inst_src,
|
||||
"expected type '{}', found type '{}'",
|
||||
.{ err_union.data.error_set, inst.ty },
|
||||
.{ err_union.data.error_set, inst_ty },
|
||||
);
|
||||
}
|
||||
},
|
||||
@ -7589,9 +7624,9 @@ fn wrapErrorUnion(
|
||||
if (!map.contains(expected_name)) {
|
||||
return sema.mod.fail(
|
||||
&block.base,
|
||||
inst.src,
|
||||
inst_src,
|
||||
"expected type '{}', found type '{}'",
|
||||
.{ err_union.data.error_set, inst.ty },
|
||||
.{ err_union.data.error_set, inst_ty },
|
||||
);
|
||||
}
|
||||
},
|
||||
@ -7602,14 +7637,14 @@ fn wrapErrorUnion(
|
||||
return sema.addConstant(dest_type, try Value.Tag.error_union.create(sema.arena, val));
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, inst.src);
|
||||
try sema.requireRuntimeBlock(block, inst_src);
|
||||
|
||||
// we are coercing from E to E!T
|
||||
if (inst.ty.zigTypeTag() == .ErrorSet) {
|
||||
var coerced = try sema.coerce(block, err_union.data.error_set, inst, inst.src);
|
||||
if (inst_ty.zigTypeTag() == .ErrorSet) {
|
||||
var coerced = try sema.coerce(block, err_union.data.error_set, inst, inst_src);
|
||||
return block.addTyOp(.wrap_errunion_err, dest_type, coerced);
|
||||
} else {
|
||||
var coerced = try sema.coerce(block, err_union.data.payload, inst, inst.src);
|
||||
var coerced = try sema.coerce(block, err_union.data.payload, inst, inst_src);
|
||||
return block.addTyOp(.wrap_errunion_payload, dest_type, coerced);
|
||||
}
|
||||
}
|
||||
@ -8081,7 +8116,10 @@ fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type {
|
||||
|
||||
.ptrtoint => return Type.initTag(.usize),
|
||||
|
||||
.call => @panic("TODO Sema.typeOf call"),
|
||||
.call => {
|
||||
const callee_ty = sema.typeOf(air_datas[i].pl_op.operand);
|
||||
return callee_ty.fnReturnType();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -8219,3 +8257,12 @@ fn getBreakBlock(sema: *Sema, inst_index: Air.Inst.Index) ?Air.Inst.Index {
|
||||
else => return null,
|
||||
}
|
||||
}
|
||||
|
||||
fn isComptimeKnown(
|
||||
sema: *Sema,
|
||||
block: *Scope.Block,
|
||||
src: LazySrcLoc,
|
||||
inst: Air.Inst.Ref,
|
||||
) !bool {
|
||||
return (try sema.resolvePossiblyUndefinedValue(block, src, inst)) != null;
|
||||
}
|
||||
|
||||
@ -1700,7 +1700,7 @@ pub const Value = extern union {
|
||||
/// peer type resolution. This is stored in a separate list so that
|
||||
/// the items are contiguous in memory and thus can be passed to
|
||||
/// `Module.resolvePeerTypes`.
|
||||
stored_inst_list: std.ArrayListUnmanaged(Air.Inst.Index) = .{},
|
||||
stored_inst_list: std.ArrayListUnmanaged(Air.Inst.Ref) = .{},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user