diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-10-03 12:51:59 +0300 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-10-05 17:26:29 +0300 |
| commit | c0350cf87eaae64ca81e17aef8872e8e55767437 (patch) | |
| tree | a65fb350db2a802c678d739cfd6f38c7fe132264 | |
| parent | 3234e8de3a50575195fab625f818a6e5fe141c7b (diff) | |
| download | zig-c0350cf87eaae64ca81e17aef8872e8e55767437.tar.gz zig-c0350cf87eaae64ca81e17aef8872e8e55767437.zip | |
Sema: avoid passing undefined as reason to `failWithNeededComptime`
Closes #13046
| -rw-r--r-- | src/Sema.zig | 50 | ||||
| -rw-r--r-- | test/cases/compile_errors/stage1/obj/runtime_value_in_switch_prong.zig | 14 |
2 files changed, 39 insertions, 25 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index c185752dc0..109b6f2a22 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2469,7 +2469,7 @@ fn createAnonymousDeclTypeNamed( const arg = sema.inst_map.get(zir_inst).?; // The comptime call code in analyzeCall already did this, so we're // just repeating it here and it's guaranteed to work. - const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, undefined) catch unreachable; + const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, "") catch unreachable; if (arg_i != 0) try buf.appendSlice(","); try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)}); @@ -5631,7 +5631,7 @@ fn zirCall( var bound_arg_src: ?LazySrcLoc = null; if (func_type.tag() == .bound_fn) { bound_arg_src = func_src; - const bound_func = try sema.resolveValue(block, .unneeded, func, undefined); + const bound_func = try sema.resolveValue(block, .unneeded, func, ""); const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; func = bound_data.func_inst; resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_len + 1); @@ -6213,7 +6213,7 @@ fn analyzeCall( } if (should_memoize and is_comptime_call) { - const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, undefined); + const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, ""); // TODO: check whether any external comptime memory was mutated by the // comptime function call. If so, then do not memoize the call here. @@ -6724,12 +6724,12 @@ fn instantiateGenericCall( const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val); child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); } else { - return sema.failWithNeededComptime(block, .unneeded, undefined); + return sema.failWithNeededComptime(block, .unneeded, ""); } } else if (is_anytype) { const arg_ty = sema.typeOf(arg); if (try sema.typeRequiresComptime(arg_ty)) { - const arg_val = try sema.resolveConstValue(block, .unneeded, arg, undefined); + const arg_val = try sema.resolveConstValue(block, .unneeded, arg, ""); const child_arg = try child_sema.addConstant(arg_ty, arg_val); child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); } else { @@ -6751,7 +6751,7 @@ fn instantiateGenericCall( } return err; }; - const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable; + const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst, "") catch unreachable; const new_func = new_func_val.castTag(.function).?.data; errdefer new_func.deinit(gpa); assert(new_func == new_module_func); @@ -9115,7 +9115,7 @@ fn zirSwitchCapture( const union_obj = operand_ty.cast(Type.Payload.Union).?.data; const first_item = try sema.resolveInst(items[0]); // Previous switch validation ensured this will succeed - const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, undefined) catch unreachable; + const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, "") catch unreachable; const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, sema.mod).?); const first_field = union_obj.fields.values()[first_field_index]; @@ -9123,7 +9123,7 @@ fn zirSwitchCapture( for (items[1..]) |item, i| { const item_ref = try sema.resolveInst(item); // Previous switch validation ensured this will succeed - const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; + const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable; const field_index = operand_ty.unionTagFieldIndex(item_val, sema.mod).?; const field = union_obj.fields.values()[field_index]; @@ -9184,7 +9184,7 @@ fn zirSwitchCapture( for (items) |item| { const item_ref = try sema.resolveInst(item); // Previous switch validation ensured this will succeed - const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; + const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable; names.putAssumeCapacityNoClobber( item_val.getError().?, {}, @@ -9198,7 +9198,7 @@ fn zirSwitchCapture( } else { const item_ref = try sema.resolveInst(items[0]); // Previous switch validation ensured this will succeed - const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; + const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable; const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?); return sema.bitCast(block, item_ty, operand, operand_src); @@ -9943,7 +9943,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError const item = try sema.resolveInst(item_ref); // Validation above ensured these will succeed. - const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable; + const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable; if (operand_val.eql(item_val, operand_ty, sema.mod)) { if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); @@ -9966,7 +9966,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError for (items) |item_ref| { const item = try sema.resolveInst(item_ref); // Validation above ensured these will succeed. - const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable; + const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable; if (operand_val.eql(item_val, operand_ty, sema.mod)) { if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); @@ -9981,8 +9981,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError extra_index += 1; // Validation above ensured these will succeed. - const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, undefined) catch unreachable; - const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, undefined) catch unreachable; + const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, "") catch unreachable; + const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, "") catch unreachable; if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty))) { @@ -10048,7 +10048,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError // `item` is already guaranteed to be constant known. const analyze_body = if (union_originally) blk: { - const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable; + const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable; const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod); break :blk field_ty.zigTypeTag() != .NoReturn; } else true; @@ -10199,7 +10199,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError const analyze_body = if (union_originally) for (items) |item_ref| { const item = try sema.resolveInst(item_ref); - const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable; + const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable; const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod); if (field_ty.zigTypeTag() != .NoReturn) break true; } else false @@ -10587,7 +10587,7 @@ fn resolveSwitchItemVal( // Constructing a LazySrcLoc is costly because we only have the switch AST node. // Only if we know for sure we need to report a compile error do we resolve the // full source locations. - if (sema.resolveConstValue(block, .unneeded, item, undefined)) |val| { + if (sema.resolveConstValue(block, .unneeded, item, "")) |val| { return TypedValue{ .ty = item_ty, .val = val }; } else |err| switch (err) { error.NeededSourceLocation => { @@ -17094,7 +17094,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air try sema.resolveTypeLayout(block, operand_src, operand_ty); const enum_ty = switch (operand_ty.zigTypeTag()) { .EnumLiteral => { - const val = try sema.resolveConstValue(block, .unneeded, operand, undefined); + const val = try sema.resolveConstValue(block, .unneeded, operand, ""); const bytes = val.castTag(.enum_literal).?.data; return sema.addStrLit(block, bytes); }, @@ -20069,7 +20069,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError var bound_arg_src: ?LazySrcLoc = null; if (sema.typeOf(func).tag() == .bound_fn) { bound_arg_src = func_src; - const bound_func = try sema.resolveValue(block, .unneeded, func, undefined); + const bound_func = try sema.resolveValue(block, .unneeded, func, ""); const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; func = bound_data.func_inst; resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount() + 1); @@ -22020,7 +22020,7 @@ fn fieldPtr( } }, .Type => { - _ = try sema.resolveConstValue(block, .unneeded, object_ptr, undefined); + _ = try sema.resolveConstValue(block, .unneeded, object_ptr, ""); const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src); const inner = if (is_pointer_to) try sema.analyzeLoad(block, src, result, object_ptr_src) @@ -23348,7 +23348,7 @@ fn coerceExtra( // Function body to function pointer. if (inst_ty.zigTypeTag() == .Fn) { - const fn_val = try sema.resolveConstValue(block, .unneeded, inst, undefined); + const fn_val = try sema.resolveConstValue(block, .unneeded, inst, ""); const fn_decl = fn_val.pointerDecl().?; const inst_as_ptr = try sema.analyzeDeclRef(fn_decl); return sema.coerce(block, dest_ty, inst_as_ptr, inst_src); @@ -23650,7 +23650,7 @@ fn coerceExtra( }, .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) { .ComptimeFloat => { - const val = try sema.resolveConstValue(block, .unneeded, inst, undefined); + const val = try sema.resolveConstValue(block, .unneeded, inst, ""); const result_val = try val.floatCast(sema.arena, dest_ty, target); return try sema.addConstant(dest_ty, result_val); }, @@ -23708,7 +23708,7 @@ fn coerceExtra( .Enum => switch (inst_ty.zigTypeTag()) { .EnumLiteral => { // enum literal to enum - const val = try sema.resolveConstValue(block, .unneeded, inst, undefined); + const val = try sema.resolveConstValue(block, .unneeded, inst, ""); const bytes = val.castTag(.enum_literal).?.data; const field_index = dest_ty.enumFieldIndex(bytes) orelse { const msg = msg: { @@ -24778,7 +24778,7 @@ fn coerceVarArgParam( .{}, ), .Fn => blk: { - const fn_val = try sema.resolveConstValue(block, .unneeded, inst, undefined); + const fn_val = try sema.resolveConstValue(block, .unneeded, inst, ""); const fn_decl = fn_val.pointerDecl().?; break :blk try sema.analyzeDeclRef(fn_decl); }, @@ -27202,7 +27202,7 @@ fn analyzeSlice( if (!end_is_len) { break :e try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); } - return sema.fail(block, end_src, "slice of pointer must include end value", .{}); + return sema.fail(block, src, "slice of pointer must include end value", .{}); }; const sentinel = s: { diff --git a/test/cases/compile_errors/stage1/obj/runtime_value_in_switch_prong.zig b/test/cases/compile_errors/stage1/obj/runtime_value_in_switch_prong.zig new file mode 100644 index 0000000000..0d15195ef1 --- /dev/null +++ b/test/cases/compile_errors/stage1/obj/runtime_value_in_switch_prong.zig @@ -0,0 +1,14 @@ +pub export fn entry() void { + var byte: u8 = 1; + switch (byte) { + byte => {}, + else => {}, + } +} + +// error +// backend=stage2 +// target=native +// +// :4:9: error: unable to resolve comptime value +// :4:9: note: switch prong values must be comptime known |
