Call ensureResultUsed before comptime .call is evaluated.

Fixes #12580
This commit is contained in:
shwqf 2022-12-18 10:09:35 +08:00 committed by Andrew Kelley
parent 2acdea7dfd
commit 23c09598c7
2 changed files with 26 additions and 8 deletions

View File

@ -3153,17 +3153,16 @@ fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
const operand = try sema.resolveInst(inst_data.operand); const operand = try sema.resolveInst(inst_data.operand);
const src = inst_data.src(); const src = inst_data.src();
return sema.ensureResultUsed(block, operand, src); return sema.ensureResultUsed(block, sema.typeOf(operand), src);
} }
fn ensureResultUsed( fn ensureResultUsed(
sema: *Sema, sema: *Sema,
block: *Block, block: *Block,
operand: Air.Inst.Ref, ty: Type,
src: LazySrcLoc, src: LazySrcLoc,
) CompileError!void { ) CompileError!void {
const operand_ty = sema.typeOf(operand); switch (ty.zigTypeTag()) {
switch (operand_ty.zigTypeTag()) {
.Void, .NoReturn => return, .Void, .NoReturn => return,
.ErrorSet, .ErrorUnion => { .ErrorSet, .ErrorUnion => {
const msg = msg: { const msg = msg: {
@ -3176,7 +3175,7 @@ fn ensureResultUsed(
}, },
else => { else => {
const msg = msg: { const msg = msg: {
const msg = try sema.errMsg(block, src, "value of type '{}' ignored", .{operand_ty.fmt(sema.mod)}); const msg = try sema.errMsg(block, src, "value of type '{}' ignored", .{ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
try sema.errNote(block, src, msg, "all non-void values must be used", .{}); try sema.errNote(block, src, msg, "all non-void values must be used", .{});
try sema.errNote(block, src, msg, "this error can be suppressed by assigning the value to '_'", .{}); try sema.errNote(block, src, msg, "this error can be suppressed by assigning the value to '_'", .{});
@ -6487,6 +6486,10 @@ fn analyzeCall(
}; };
} }
if (is_comptime_call and ensure_result_used) {
try sema.ensureResultUsed(block, fn_ret_ty, call_src);
}
const result = result: { const result = result: {
sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) { sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
error.ComptimeReturn => break :result inlining.comptime_result, error.ComptimeReturn => break :result inlining.comptime_result,
@ -6609,7 +6612,7 @@ fn analyzeCall(
}; };
if (ensure_result_used) { if (ensure_result_used) {
try sema.ensureResultUsed(block, result, call_src); try sema.ensureResultUsed(block, sema.typeOf(result), call_src);
} }
if (call_tag == .call_always_tail) { if (call_tag == .call_always_tail) {
return sema.handleTailCall(block, call_src, func_ty, result); return sema.handleTailCall(block, call_src, func_ty, result);
@ -7251,7 +7254,7 @@ fn instantiateGenericCall(
sema.appendRefsAssumeCapacity(runtime_args); sema.appendRefsAssumeCapacity(runtime_args);
if (ensure_result_used) { if (ensure_result_used) {
try sema.ensureResultUsed(block, result, call_src); try sema.ensureResultUsed(block, sema.typeOf(result), call_src);
} }
if (call_tag == .call_always_tail) { if (call_tag == .call_always_tail) {
return sema.handleTailCall(block, call_src, func_ty, result); return sema.handleTailCall(block, call_src, func_ty, result);

View File

@ -1,6 +1,18 @@
export fn foo() void { export fn a() void {
comptime 1; comptime 1;
} }
export fn b() void {
comptime bar();
}
fn bar() u8 {
const u32_max = @import("std").math.maxInt(u32);
@setEvalBranchQuota(u32_max);
var x: u32 = 0;
while (x != u32_max) : (x +%= 1) {}
return 0;
}
// error // error
// backend=stage2 // backend=stage2
@ -9,3 +21,6 @@ export fn foo() void {
// :2:5: error: value of type 'comptime_int' ignored // :2:5: error: value of type 'comptime_int' ignored
// :2:5: note: all non-void values must be used // :2:5: note: all non-void values must be used
// :2:5: note: this error can be suppressed by assigning the value to '_' // :2:5: note: this error can be suppressed by assigning the value to '_'
// :5:17: error: value of type 'u8' ignored
// :5:17: note: all non-void values must be used
// :5:17: note: this error can be suppressed by assigning the value to '_'