diff --git a/src/Sema.zig b/src/Sema.zig index 52eba5bc5c..44daa02780 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -17961,20 +17961,21 @@ fn finishStructInit( return sema.failWithOwnedErrorMsg(msg); } - const is_comptime = for (field_inits) |field_init| { + // Find which field forces the expression to be runtime, if any. + const opt_runtime_index = for (field_inits, 0..) |field_init, i| { if (!(try sema.isComptimeKnown(field_init))) { - break false; + break i; } - } else true; + } else null; - if (is_comptime) { + const runtime_index = opt_runtime_index orelse { const values = try sema.arena.alloc(Value, field_inits.len); for (field_inits, 0..) |field_init, i| { values[i] = (sema.resolveMaybeUndefVal(field_init) catch unreachable).?; } const struct_val = try Value.Tag.aggregate.create(sema.arena, values); return sema.addConstantMaybeRef(block, struct_ty, struct_val, is_ref); - } + }; if (is_ref) { try sema.resolveStructLayout(struct_ty); @@ -17994,7 +17995,15 @@ fn finishStructInit( return sema.makePtrConst(block, alloc); } - try sema.requireRuntimeBlock(block, dest_src, null); + sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) { + error.NeededSourceLocation => { + const decl = sema.mod.declPtr(block.src_decl); + const field_src = Module.initSrc(dest_src.node_offset.x, sema.gpa, decl, runtime_index); + try sema.requireRuntimeBlock(block, dest_src, field_src); + unreachable; + }, + else => |e| return e, + }; try sema.queueFullTypeResolution(struct_ty); return block.addAggregateInit(struct_ty, field_inits); } @@ -18014,6 +18023,7 @@ fn zirStructInitAnon( defer fields.deinit(sema.gpa); try fields.ensureUnusedCapacity(sema.gpa, types.len); + // Find which field forces the expression to be runtime, if any. const opt_runtime_index = rs: { var runtime_index: ?usize = null; var extra_index = extra.end; diff --git a/test/cases/compile_errors/unable_to_evaluate_comptime_expr.zig b/test/cases/compile_errors/unable_to_evaluate_comptime_expr.zig new file mode 100644 index 0000000000..1c439316bc --- /dev/null +++ b/test/cases/compile_errors/unable_to_evaluate_comptime_expr.zig @@ -0,0 +1,26 @@ +var n: u8 = 5; + +const S = struct { + a: u8, +}; + +var a: S = .{ .a = n }; + +pub export fn entry1() void { + _ = a; +} + +var b: S = S{ .a = n }; + +pub export fn entry2() void { + _ = b; +} + +// error +// backend=stage2 +// target=native +// +// :7:13: error: unable to evaluate comptime expression +// :7:16: note: operation is runtime due to this operand +// :13:13: error: unable to evaluate comptime expression +// :13:16: note: operation is runtime due to this operand diff --git a/test/cases/compile_errors/unable_to_evaluate_comptime_expr_with_inferred_type.zig b/test/cases/compile_errors/unable_to_evaluate_comptime_expr_with_inferred_type.zig deleted file mode 100644 index 3792cf2f82..0000000000 --- a/test/cases/compile_errors/unable_to_evaluate_comptime_expr_with_inferred_type.zig +++ /dev/null @@ -1,17 +0,0 @@ -const A = struct { - a: u8, -}; - -var n: u8 = 5; -var a: A = .{ .a = n }; - -pub export fn entry() void { - _ = a; -} - -// error -// backend=stage2 -// target=native -// -// :6:13: error: unable to evaluate comptime expression -// :6:16: note: operation is runtime due to this operand