diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-12-27 17:56:33 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-12-27 17:56:33 -0700 |
| commit | 9dd4fb4130a71d2aaaaa361d8ee0b7135cb84162 (patch) | |
| tree | 569ebd4a536b1df12976d6c6c19e3725ef6b7e98 /src | |
| parent | 886df772f06377df95f867e8b18ee47bbd0fcd8b (diff) | |
| download | zig-9dd4fb4130a71d2aaaaa361d8ee0b7135cb84162.tar.gz zig-9dd4fb4130a71d2aaaaa361d8ee0b7135cb84162.zip | |
stage2: fix 0-bit function parameters
Before this commit, Zig would incorrectly emit `arg` AIR instructions
for parameters whose types were 0-bit.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 24 | ||||
| -rw-r--r-- | src/Sema.zig | 8 |
2 files changed, 22 insertions, 10 deletions
diff --git a/src/Module.zig b/src/Module.zig index 25e262855c..2c5c01bb7a 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -4327,16 +4327,16 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem var runtime_param_index: usize = 0; var total_param_index: usize = 0; for (fn_info.param_body) |inst| { - const name = switch (zir_tags[inst]) { + const param: struct { name: u32, src: LazySrcLoc } = switch (zir_tags[inst]) { .param, .param_comptime => blk: { - const inst_data = sema.code.instructions.items(.data)[inst].pl_tok; - const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index).data; - break :blk extra.name; + const pl_tok = sema.code.instructions.items(.data)[inst].pl_tok; + const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index).data; + break :blk .{ .name = extra.name, .src = pl_tok.src() }; }, .param_anytype, .param_anytype_comptime => blk: { const str_tok = sema.code.instructions.items(.data)[inst].str_tok; - break :blk str_tok.start; + break :blk .{ .name = str_tok.start, .src = str_tok.src() }; }, else => continue, @@ -4352,6 +4352,18 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem } } const param_type = fn_ty.fnParamType(runtime_param_index); + const opt_opv = sema.typeHasOnePossibleValue(&inner_block, param.src, param_type) catch |err| switch (err) { + error.NeededSourceLocation => unreachable, + error.GenericPoison => unreachable, + error.ComptimeReturn => unreachable, + else => |e| return e, + }; + if (opt_opv) |opv| { + const arg = try sema.addConstant(param_type, opv); + sema.inst_map.putAssumeCapacityNoClobber(inst, arg); + total_param_index += 1; + continue; + } const ty_ref = try sema.addType(param_type); const arg_index = @intCast(u32, sema.air_instructions.len); inner_block.instructions.appendAssumeCapacity(arg_index); @@ -4359,7 +4371,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem .tag = .arg, .data = .{ .ty_str = .{ .ty = ty_ref, - .str = name, + .str = param.name, } }, }); sema.inst_map.putAssumeCapacityNoClobber(inst, Air.indexToRef(arg_index)); diff --git a/src/Sema.zig b/src/Sema.zig index d273d1d6e8..f1431272db 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -266,7 +266,7 @@ pub const Block = struct { }); } - pub fn addBinOp( + fn addBinOp( block: *Block, tag: Air.Inst.Tag, lhs: Air.Inst.Ref, @@ -281,7 +281,7 @@ pub const Block = struct { }); } - pub fn addArg(block: *Block, ty: Type, name: u32) error{OutOfMemory}!Air.Inst.Ref { + fn addArg(block: *Block, ty: Type, name: u32) error{OutOfMemory}!Air.Inst.Ref { return block.addInst(.{ .tag = .arg, .data = .{ .ty_str = .{ @@ -291,7 +291,7 @@ pub const Block = struct { }); } - pub fn addStructFieldPtr( + fn addStructFieldPtr( block: *Block, struct_ptr: Air.Inst.Ref, field_index: u32, @@ -15339,7 +15339,7 @@ fn getBuiltinType( /// in `Sema` is for calling during semantic analysis, and performs field resolution /// to get the answer. The one in `Type` is for calling during codegen and asserts /// that the types are already resolved. -fn typeHasOnePossibleValue( +pub fn typeHasOnePossibleValue( sema: *Sema, block: *Block, src: LazySrcLoc, |
