Sema: migrate zirResolveInferredAlloc to new anon decl mechanism

This required a bug fix in zirMakePtrConst.
This commit is contained in:
Andrew Kelley 2023-10-19 16:49:34 -07:00
parent 7bab406c79
commit 5e1db5e478

View File

@ -3672,10 +3672,18 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
implicit_ct: {
const ptr_val = try sema.resolveMaybeUndefVal(alloc) orelse break :implicit_ct;
if (!ptr_val.isComptimeMutablePtr(mod)) {
// It could still be a constant pointer to a decl
const decl_index = ptr_val.pointerDecl(mod) orelse break :implicit_ct;
const decl_val = mod.declPtr(decl_index).val.toIntern();
if (mod.intern_pool.isRuntimeValue(decl_val)) break :implicit_ct;
// It could still be a constant pointer to a decl.
switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
.anon_decl => |anon_decl| {
if (mod.intern_pool.isVariable(anon_decl.val))
break :implicit_ct;
},
else => {
const decl_index = ptr_val.pointerDecl(mod) orelse break :implicit_ct;
const decl_val = mod.declPtr(decl_index).val.toIntern();
if (mod.intern_pool.isRuntimeValue(decl_val)) break :implicit_ct;
},
}
}
return sema.makePtrConst(block, alloc);
}
@ -3915,17 +3923,19 @@ fn finishResolveComptimeKnownAllocValue(sema: *Sema, result_val: InternPool.Inde
return result_val;
}
fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const alloc_ty = sema.typeOf(alloc);
var ptr_info = alloc_ty.ptrInfo(mod);
fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {
var ptr_info = ptr_ty.ptrInfo(sema.mod);
ptr_info.flags.is_const = true;
const const_ptr_ty = try sema.ptrType(ptr_info);
return sema.ptrType(ptr_info);
}
fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {
const alloc_ty = sema.typeOf(alloc);
const const_ptr_ty = try sema.makePtrTyConst(alloc_ty);
// Detect if a comptime value simply needs to have its type changed.
if (try sema.resolveMaybeUndefVal(alloc)) |val| {
return Air.internedToRef((try mod.getCoerced(val, const_ptr_ty)).toIntern());
return Air.internedToRef((try sema.mod.getCoerced(val, const_ptr_ty)).toIntern());
}
return block.addBitCast(const_ptr_ty, alloc);
@ -4039,6 +4049,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
defer tracy.end();
const mod = sema.mod;
const gpa = sema.gpa;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
@ -4104,11 +4115,14 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
if (!ia1.is_const) {
try sema.validateVarType(block, ty_src, final_elem_ty, false);
} else if (try sema.resolveComptimeKnownAllocValue(block, ptr, final_ptr_ty)) |val| {
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
const new_decl_index = try anon_decl.finish(final_elem_ty, val.toValue(), ia1.alignment);
const new_mut_ptr = Air.refToInterned(try sema.analyzeDeclRef(new_decl_index)).?.toValue();
const new_const_ptr = (try mod.getCoerced(new_mut_ptr, final_ptr_ty)).toIntern();
const const_ptr_ty = (try sema.makePtrTyConst(final_ptr_ty)).toIntern();
const new_const_ptr = try mod.intern(.{ .ptr = .{
.ty = const_ptr_ty,
.addr = .{ .anon_decl = .{
.val = val,
.orig_ty = const_ptr_ty,
} },
} });
// Remap the ZIR oeprand to the resolved pointer value
sema.inst_map.putAssumeCapacity(Zir.refToIndex(inst_data.operand).?, Air.internedToRef(new_const_ptr));
@ -4131,7 +4145,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
// Now we need to go back over all the store instructions, and do the logic as if
// the new result ptr type was available.
const gpa = sema.gpa;
for (ia2.prongs.items) |placeholder_inst| {
var replacement_block = block.makeSubBlock();