Sema: avoid passing undefined as reason to failWithNeededComptime
Closes #13046
This commit is contained in:
50
src/Sema.zig
50
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: {
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user