| ... | @@ -151,6 +151,8 @@ pub const Block = struct { | ... | @@ -151,6 +151,8 @@ pub const Block = struct { |
| 151 | runtime_index: Value.RuntimeIndex = .zero, | 151 | runtime_index: Value.RuntimeIndex = .zero, |
| 152 | inline_block: Zir.Inst.Index = 0, | 152 | inline_block: Zir.Inst.Index = 0, |
| 153 | | 153 | |
| | 154 | comptime_reason: ?*const ComptimeReason = null, |
| | 155 | // TODO is_comptime and comptime_reason should probably be merged together. |
| 154 | is_comptime: bool, | 156 | is_comptime: bool, |
| 155 | is_typeof: bool = false, | 157 | is_typeof: bool = false, |
| 156 | is_coerce_result_ptr: bool = false, | 158 | is_coerce_result_ptr: bool = false, |
| ... | @@ -173,6 +175,49 @@ pub const Block = struct { | ... | @@ -173,6 +175,49 @@ pub const Block = struct { |
| 173 | /// Value for switch_capture in an inline case | 175 | /// Value for switch_capture in an inline case |
| 174 | inline_case_capture: Air.Inst.Ref = .none, | 176 | inline_case_capture: Air.Inst.Ref = .none, |
| 175 | | 177 | |
| | 178 | const ComptimeReason = union(enum) { |
| | 179 | c_import: struct { |
| | 180 | block: *Block, |
| | 181 | src: LazySrcLoc, |
| | 182 | }, |
| | 183 | comptime_ret_ty: struct { |
| | 184 | block: *Block, |
| | 185 | func: Air.Inst.Ref, |
| | 186 | func_src: LazySrcLoc, |
| | 187 | return_ty: Type, |
| | 188 | }, |
| | 189 | |
| | 190 | fn explain(cr: ComptimeReason, sema: *Sema, msg: ?*Module.ErrorMsg) !void { |
| | 191 | const parent = msg orelse return; |
| | 192 | const prefix = "expression is evaluated at comptime because "; |
| | 193 | switch (cr) { |
| | 194 | .c_import => |ci| { |
| | 195 | try sema.errNote(ci.block, ci.src, parent, prefix ++ "it is inside a @cImport", .{}); |
| | 196 | }, |
| | 197 | .comptime_ret_ty => |rt| { |
| | 198 | const src_loc = if (try sema.funcDeclSrc(rt.block, rt.func_src, rt.func)) |capture| blk: { |
| | 199 | var src_loc = capture; |
| | 200 | src_loc.lazy = .{ .node_offset_fn_type_ret_ty = 0 }; |
| | 201 | break :blk src_loc; |
| | 202 | } else blk: { |
| | 203 | const src_decl = sema.mod.declPtr(rt.block.src_decl); |
| | 204 | break :blk rt.func_src.toSrcLoc(src_decl); |
| | 205 | }; |
| | 206 | if (rt.return_ty.tag() == .generic_poison) { |
| | 207 | return sema.mod.errNoteNonLazy(src_loc, parent, prefix ++ "the generic function was instantiated with a comptime-only return type", .{}); |
| | 208 | } |
| | 209 | try sema.mod.errNoteNonLazy( |
| | 210 | src_loc, |
| | 211 | parent, |
| | 212 | prefix ++ "the function returns a comptime-only type '{}'", |
| | 213 | .{rt.return_ty.fmt(sema.mod)}, |
| | 214 | ); |
| | 215 | try sema.explainWhyTypeIsComptime(rt.block, rt.func_src, parent, src_loc, rt.return_ty); |
| | 216 | }, |
| | 217 | } |
| | 218 | } |
| | 219 | }; |
| | 220 | |
| 176 | const Param = struct { | 221 | const Param = struct { |
| 177 | /// `noreturn` means `anytype`. | 222 | /// `noreturn` means `anytype`. |
| 178 | ty: Type, | 223 | ty: Type, |
| ... | @@ -224,6 +269,7 @@ pub const Block = struct { | ... | @@ -224,6 +269,7 @@ pub const Block = struct { |
| 224 | .label = null, | 269 | .label = null, |
| 225 | .inlining = parent.inlining, | 270 | .inlining = parent.inlining, |
| 226 | .is_comptime = parent.is_comptime, | 271 | .is_comptime = parent.is_comptime, |
| | 272 | .comptime_reason = parent.comptime_reason, |
| 227 | .is_typeof = parent.is_typeof, | 273 | .is_typeof = parent.is_typeof, |
| 228 | .runtime_cond = parent.runtime_cond, | 274 | .runtime_cond = parent.runtime_cond, |
| 229 | .runtime_loop = parent.runtime_loop, | 275 | .runtime_loop = parent.runtime_loop, |
| ... | @@ -1420,7 +1466,10 @@ fn analyzeBodyInner( | ... | @@ -1420,7 +1466,10 @@ fn analyzeBodyInner( |
| 1420 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); | 1466 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); |
| 1421 | const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len]; | 1467 | const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len]; |
| 1422 | const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; | 1468 | const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; |
| 1423 | const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime-known"); | 1469 | const cond = sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime-known") catch |err| { |
| | 1470 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); |
| | 1471 | return err; |
| | 1472 | }; |
| 1424 | const inline_body = if (cond.val.toBool()) then_body else else_body; | 1473 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 1425 | | 1474 | |
| 1426 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); | 1475 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
| ... | @@ -1438,7 +1487,10 @@ fn analyzeBodyInner( | ... | @@ -1438,7 +1487,10 @@ fn analyzeBodyInner( |
| 1438 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); | 1487 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); |
| 1439 | const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len]; | 1488 | const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len]; |
| 1440 | const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; | 1489 | const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; |
| 1441 | const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime-known"); | 1490 | const cond = sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime-known") catch |err| { |
| | 1491 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); |
| | 1492 | return err; |
| | 1493 | }; |
| 1442 | const inline_body = if (cond.val.toBool()) then_body else else_body; | 1494 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 1443 | const old_runtime_index = block.runtime_index; | 1495 | const old_runtime_index = block.runtime_index; |
| 1444 | defer block.runtime_index = old_runtime_index; | 1496 | defer block.runtime_index = old_runtime_index; |
| ... | @@ -1460,7 +1512,10 @@ fn analyzeBodyInner( | ... | @@ -1460,7 +1512,10 @@ fn analyzeBodyInner( |
| 1460 | const err_union = try sema.resolveInst(extra.data.operand); | 1512 | const err_union = try sema.resolveInst(extra.data.operand); |
| 1461 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); | 1513 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); |
| 1462 | assert(is_non_err != .none); | 1514 | assert(is_non_err != .none); |
| 1463 | const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err, "try operand inside comptime block must be comptime-known"); | 1515 | const is_non_err_tv = sema.resolveInstConst(block, operand_src, is_non_err, "try operand inside comptime block must be comptime-known") catch |err| { |
| | 1516 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); |
| | 1517 | return err; |
| | 1518 | }; |
| 1464 | if (is_non_err_tv.val.toBool()) { | 1519 | if (is_non_err_tv.val.toBool()) { |
| 1465 | const err_union_ty = sema.typeOf(err_union); | 1520 | const err_union_ty = sema.typeOf(err_union); |
| 1466 | break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false); | 1521 | break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false); |
| ... | @@ -1516,7 +1571,10 @@ fn analyzeBodyInner( | ... | @@ -1516,7 +1571,10 @@ fn analyzeBodyInner( |
| 1516 | const err_union = try sema.analyzeLoad(block, src, operand, operand_src); | 1571 | const err_union = try sema.analyzeLoad(block, src, operand, operand_src); |
| 1517 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); | 1572 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); |
| 1518 | assert(is_non_err != .none); | 1573 | assert(is_non_err != .none); |
| 1519 | const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err, "try operand inside comptime block must be comptime-known"); | 1574 | const is_non_err_tv = sema.resolveInstConst(block, operand_src, is_non_err, "try operand inside comptime block must be comptime-known") catch |err| { |
| | 1575 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); |
| | 1576 | return err; |
| | 1577 | }; |
| 1520 | if (is_non_err_tv.val.toBool()) { | 1578 | if (is_non_err_tv.val.toBool()) { |
| 1521 | break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); | 1579 | break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); |
| 1522 | } | 1580 | } |
| ... | @@ -1675,8 +1733,8 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) | ... | @@ -1675,8 +1733,8 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) |
| 1675 | return; | 1733 | return; |
| 1676 | } | 1734 | } |
| 1677 | | 1735 | |
| | 1736 | assert(!block.is_comptime); |
| 1678 | var err_trace_block = block.makeSubBlock(); | 1737 | var err_trace_block = block.makeSubBlock(); |
| 1679 | err_trace_block.is_comptime = false; | | |
| 1680 | defer err_trace_block.instructions.deinit(sema.gpa); | 1738 | defer err_trace_block.instructions.deinit(sema.gpa); |
| 1681 | | 1739 | |
| 1682 | const src: LazySrcLoc = .unneeded; | 1740 | const src: LazySrcLoc = .unneeded; |
| ... | @@ -4944,6 +5002,10 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -4944,6 +5002,10 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 4944 | var c_import_buf = std.ArrayList(u8).init(sema.gpa); | 5002 | var c_import_buf = std.ArrayList(u8).init(sema.gpa); |
| 4945 | defer c_import_buf.deinit(); | 5003 | defer c_import_buf.deinit(); |
| 4946 | | 5004 | |
| | 5005 | var comptime_reason = .{ .c_import = .{ |
| | 5006 | .block = parent_block, |
| | 5007 | .src = src, |
| | 5008 | } }; |
| 4947 | var child_block: Block = .{ | 5009 | var child_block: Block = .{ |
| 4948 | .parent = parent_block, | 5010 | .parent = parent_block, |
| 4949 | .sema = sema, | 5011 | .sema = sema, |
| ... | @@ -4952,7 +5014,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -4952,7 +5014,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 4952 | .wip_capture_scope = parent_block.wip_capture_scope, | 5014 | .wip_capture_scope = parent_block.wip_capture_scope, |
| 4953 | .instructions = .{}, | 5015 | .instructions = .{}, |
| 4954 | .inlining = parent_block.inlining, | 5016 | .inlining = parent_block.inlining, |
| 4955 | .is_comptime = parent_block.is_comptime, | 5017 | .is_comptime = true, |
| | 5018 | .comptime_reason = &comptime_reason, |
| 4956 | .c_import_buf = &c_import_buf, | 5019 | .c_import_buf = &c_import_buf, |
| 4957 | .runtime_cond = parent_block.runtime_cond, | 5020 | .runtime_cond = parent_block.runtime_cond, |
| 4958 | .runtime_loop = parent_block.runtime_loop, | 5021 | .runtime_loop = parent_block.runtime_loop, |
| ... | @@ -5053,6 +5116,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -5053,6 +5116,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro |
| 5053 | .label = &label, | 5116 | .label = &label, |
| 5054 | .inlining = parent_block.inlining, | 5117 | .inlining = parent_block.inlining, |
| 5055 | .is_comptime = parent_block.is_comptime, | 5118 | .is_comptime = parent_block.is_comptime, |
| | 5119 | .comptime_reason = parent_block.comptime_reason, |
| 5056 | .is_typeof = parent_block.is_typeof, | 5120 | .is_typeof = parent_block.is_typeof, |
| 5057 | .want_safety = parent_block.want_safety, | 5121 | .want_safety = parent_block.want_safety, |
| 5058 | .float_mode = parent_block.float_mode, | 5122 | .float_mode = parent_block.float_mode, |
| ... | @@ -5926,6 +5990,7 @@ fn zirCall( | ... | @@ -5926,6 +5990,7 @@ fn zirCall( |
| 5926 | defer block.is_comptime = parent_comptime; | 5990 | defer block.is_comptime = parent_comptime; |
| 5927 | if (arg_index < fn_params_len and func_ty_info.comptime_params[arg_index]) { | 5991 | if (arg_index < fn_params_len and func_ty_info.comptime_params[arg_index]) { |
| 5928 | block.is_comptime = true; | 5992 | block.is_comptime = true; |
| | 5993 | // TODO set comptime_reason |
| 5929 | } | 5994 | } |
| 5930 | | 5995 | |
| 5931 | const param_ty_inst = try sema.addType(param_ty); | 5996 | const param_ty_inst = try sema.addType(param_ty); |
| ... | @@ -6056,37 +6121,6 @@ const GenericCallAdapter = struct { | ... | @@ -6056,37 +6121,6 @@ const GenericCallAdapter = struct { |
| 6056 | } | 6121 | } |
| 6057 | }; | 6122 | }; |
| 6058 | | 6123 | |
| 6059 | fn addComptimeReturnTypeNote( | | |
| 6060 | sema: *Sema, | | |
| 6061 | block: *Block, | | |
| 6062 | func: Air.Inst.Ref, | | |
| 6063 | func_src: LazySrcLoc, | | |
| 6064 | return_ty: Type, | | |
| 6065 | parent: *Module.ErrorMsg, | | |
| 6066 | requires_comptime: bool, | | |
| 6067 | ) !void { | | |
| 6068 | if (!requires_comptime) return; | | |
| 6069 | | | |
| 6070 | const src_loc = if (try sema.funcDeclSrc(block, func_src, func)) |capture| blk: { | | |
| 6071 | var src_loc = capture; | | |
| 6072 | src_loc.lazy = .{ .node_offset_fn_type_ret_ty = 0 }; | | |
| 6073 | break :blk src_loc; | | |
| 6074 | } else blk: { | | |
| 6075 | const src_decl = sema.mod.declPtr(block.src_decl); | | |
| 6076 | break :blk func_src.toSrcLoc(src_decl); | | |
| 6077 | }; | | |
| 6078 | if (return_ty.tag() == .generic_poison) { | | |
| 6079 | return sema.mod.errNoteNonLazy(src_loc, parent, "generic function is instantiated with a comptime-only return type", .{}); | | |
| 6080 | } | | |
| 6081 | try sema.mod.errNoteNonLazy( | | |
| 6082 | src_loc, | | |
| 6083 | parent, | | |
| 6084 | "function is being called at comptime because it returns a comptime-only type '{}'", | | |
| 6085 | .{return_ty.fmt(sema.mod)}, | | |
| 6086 | ); | | |
| 6087 | try sema.explainWhyTypeIsComptime(block, func_src, parent, src_loc, return_ty); | | |
| 6088 | } | | |
| 6089 | | | |
| 6090 | fn analyzeCall( | 6124 | fn analyzeCall( |
| 6091 | sema: *Sema, | 6125 | sema: *Sema, |
| 6092 | block: *Block, | 6126 | block: *Block, |
| ... | @@ -6177,11 +6211,21 @@ fn analyzeCall( | ... | @@ -6177,11 +6211,21 @@ fn analyzeCall( |
| 6177 | | 6211 | |
| 6178 | var is_generic_call = func_ty_info.is_generic; | 6212 | var is_generic_call = func_ty_info.is_generic; |
| 6179 | var is_comptime_call = block.is_comptime or modifier == .compile_time; | 6213 | var is_comptime_call = block.is_comptime or modifier == .compile_time; |
| 6180 | var comptime_only_ret_ty = false; | 6214 | var comptime_reason_buf: Block.ComptimeReason = undefined; |
| | 6215 | var comptime_reason: ?*const Block.ComptimeReason = null; |
| 6181 | if (!is_comptime_call) { | 6216 | if (!is_comptime_call) { |
| 6182 | if (sema.typeRequiresComptime(func_ty_info.return_type)) |ct| { | 6217 | if (sema.typeRequiresComptime(func_ty_info.return_type)) |ct| { |
| 6183 | is_comptime_call = ct; | 6218 | is_comptime_call = ct; |
| 6184 | comptime_only_ret_ty = ct; | 6219 | if (ct) { |
| | 6220 | // stage1 can't handle doing this directly |
| | 6221 | comptime_reason_buf = .{ .comptime_ret_ty = .{ |
| | 6222 | .block = block, |
| | 6223 | .func = func, |
| | 6224 | .func_src = func_src, |
| | 6225 | .return_ty = func_ty_info.return_type, |
| | 6226 | } }; |
| | 6227 | comptime_reason = &comptime_reason_buf; |
| | 6228 | } |
| 6185 | } else |err| switch (err) { | 6229 | } else |err| switch (err) { |
| 6186 | error.GenericPoison => is_generic_call = true, | 6230 | error.GenericPoison => is_generic_call = true, |
| 6187 | else => |e| return e, | 6231 | else => |e| return e, |
| ... | @@ -6210,7 +6254,14 @@ fn analyzeCall( | ... | @@ -6210,7 +6254,14 @@ fn analyzeCall( |
| 6210 | error.ComptimeReturn => { | 6254 | error.ComptimeReturn => { |
| 6211 | is_inline_call = true; | 6255 | is_inline_call = true; |
| 6212 | is_comptime_call = true; | 6256 | is_comptime_call = true; |
| 6213 | comptime_only_ret_ty = true; | 6257 | // stage1 can't handle doing this directly |
| | 6258 | comptime_reason_buf = .{ .comptime_ret_ty = .{ |
| | 6259 | .block = block, |
| | 6260 | .func = func, |
| | 6261 | .func_src = func_src, |
| | 6262 | .return_ty = func_ty_info.return_type, |
| | 6263 | } }; |
| | 6264 | comptime_reason = &comptime_reason_buf; |
| 6214 | }, | 6265 | }, |
| 6215 | else => |e| return e, | 6266 | else => |e| return e, |
| 6216 | } | 6267 | } |
| ... | @@ -6222,9 +6273,7 @@ fn analyzeCall( | ... | @@ -6222,9 +6273,7 @@ fn analyzeCall( |
| 6222 | | 6273 | |
| 6223 | const result: Air.Inst.Ref = if (is_inline_call) res: { | 6274 | const result: Air.Inst.Ref = if (is_inline_call) res: { |
| 6224 | const func_val = sema.resolveConstValue(block, func_src, func, "function being called at comptime must be comptime-known") catch |err| { | 6275 | const func_val = sema.resolveConstValue(block, func_src, func, "function being called at comptime must be comptime-known") catch |err| { |
| 6225 | if (err == error.AnalysisFail and sema.err != null) { | 6276 | if (err == error.AnalysisFail and comptime_reason != null) try comptime_reason.?.explain(sema, sema.err); |
| 6226 | try sema.addComptimeReturnTypeNote(block, func, func_src, func_ty_info.return_type, sema.err.?, comptime_only_ret_ty); | | |
| 6227 | } | | |
| 6228 | return err; | 6277 | return err; |
| 6229 | }; | 6278 | }; |
| 6230 | const module_fn = switch (func_val.tag()) { | 6279 | const module_fn = switch (func_val.tag()) { |
| ... | @@ -6292,6 +6341,7 @@ fn analyzeCall( | ... | @@ -6292,6 +6341,7 @@ fn analyzeCall( |
| 6292 | .label = null, | 6341 | .label = null, |
| 6293 | .inlining = &inlining, | 6342 | .inlining = &inlining, |
| 6294 | .is_comptime = is_comptime_call, | 6343 | .is_comptime = is_comptime_call, |
| | 6344 | .comptime_reason = comptime_reason, |
| 6295 | .error_return_trace_index = block.error_return_trace_index, | 6345 | .error_return_trace_index = block.error_return_trace_index, |
| 6296 | }; | 6346 | }; |
| 6297 | | 6347 | |
| ... | @@ -6344,11 +6394,6 @@ fn analyzeCall( | ... | @@ -6344,11 +6394,6 @@ fn analyzeCall( |
| 6344 | is_comptime_call, | 6394 | is_comptime_call, |
| 6345 | &should_memoize, | 6395 | &should_memoize, |
| 6346 | memoized_call_key, | 6396 | memoized_call_key, |
| 6347 | // last 4 arguments are only used when reporting errors | | |
| 6348 | undefined, | | |
| 6349 | undefined, | | |
| 6350 | undefined, | | |
| 6351 | undefined, | | |
| 6352 | ) catch |err| switch (err) { | 6397 | ) catch |err| switch (err) { |
| 6353 | error.NeededSourceLocation => { | 6398 | error.NeededSourceLocation => { |
| 6354 | _ = sema.inst_map.remove(inst); | 6399 | _ = sema.inst_map.remove(inst); |
| ... | @@ -6364,10 +6409,6 @@ fn analyzeCall( | ... | @@ -6364,10 +6409,6 @@ fn analyzeCall( |
| 6364 | is_comptime_call, | 6409 | is_comptime_call, |
| 6365 | &should_memoize, | 6410 | &should_memoize, |
| 6366 | memoized_call_key, | 6411 | memoized_call_key, |
| 6367 | func, | | |
| 6368 | func_src, | | |
| 6369 | func_ty_info.return_type, | | |
| 6370 | comptime_only_ret_ty, | | |
| 6371 | ); | 6412 | ); |
| 6372 | return error.AnalysisFail; | 6413 | return error.AnalysisFail; |
| 6373 | }, | 6414 | }, |
| ... | @@ -6604,10 +6645,6 @@ fn analyzeInlineCallArg( | ... | @@ -6604,10 +6645,6 @@ fn analyzeInlineCallArg( |
| 6604 | is_comptime_call: bool, | 6645 | is_comptime_call: bool, |
| 6605 | should_memoize: *bool, | 6646 | should_memoize: *bool, |
| 6606 | memoized_call_key: Module.MemoizedCall.Key, | 6647 | memoized_call_key: Module.MemoizedCall.Key, |
| 6607 | func: Air.Inst.Ref, | | |
| 6608 | func_src: LazySrcLoc, | | |
| 6609 | ret_ty: Type, | | |
| 6610 | comptime_only_ret_ty: bool, | | |
| 6611 | ) !void { | 6648 | ) !void { |
| 6612 | const zir_tags = sema.code.instructions.items(.tag); | 6649 | const zir_tags = sema.code.instructions.items(.tag); |
| 6613 | switch (zir_tags[inst]) { | 6650 | switch (zir_tags[inst]) { |
| ... | @@ -6624,9 +6661,7 @@ fn analyzeInlineCallArg( | ... | @@ -6624,9 +6661,7 @@ fn analyzeInlineCallArg( |
| 6624 | const uncasted_arg = uncasted_args[arg_i.*]; | 6661 | const uncasted_arg = uncasted_args[arg_i.*]; |
| 6625 | if (try sema.typeRequiresComptime(param_ty)) { | 6662 | if (try sema.typeRequiresComptime(param_ty)) { |
| 6626 | _ = sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to parameter with comptime-only type must be comptime-known") catch |err| { | 6663 | _ = sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to parameter with comptime-only type must be comptime-known") catch |err| { |
| 6627 | if (err == error.AnalysisFail and sema.err != null) { | 6664 | if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err); |
| 6628 | try sema.addComptimeReturnTypeNote(arg_block, func, func_src, ret_ty, sema.err.?, comptime_only_ret_ty); | | |
| 6629 | } | | |
| 6630 | return err; | 6665 | return err; |
| 6631 | }; | 6666 | }; |
| 6632 | } | 6667 | } |
| ... | @@ -6635,9 +6670,7 @@ fn analyzeInlineCallArg( | ... | @@ -6635,9 +6670,7 @@ fn analyzeInlineCallArg( |
| 6635 | if (is_comptime_call) { | 6670 | if (is_comptime_call) { |
| 6636 | try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg); | 6671 | try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg); |
| 6637 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime-known") catch |err| { | 6672 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime-known") catch |err| { |
| 6638 | if (err == error.AnalysisFail and sema.err != null) { | 6673 | if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err); |
| 6639 | try sema.addComptimeReturnTypeNote(arg_block, func, func_src, ret_ty, sema.err.?, comptime_only_ret_ty); | | |
| 6640 | } | | |
| 6641 | return err; | 6674 | return err; |
| 6642 | }; | 6675 | }; |
| 6643 | switch (arg_val.tag()) { | 6676 | switch (arg_val.tag()) { |
| ... | @@ -6679,9 +6712,7 @@ fn analyzeInlineCallArg( | ... | @@ -6679,9 +6712,7 @@ fn analyzeInlineCallArg( |
| 6679 | if (is_comptime_call) { | 6712 | if (is_comptime_call) { |
| 6680 | try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg); | 6713 | try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg); |
| 6681 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime-known") catch |err| { | 6714 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime-known") catch |err| { |
| 6682 | if (err == error.AnalysisFail and sema.err != null) { | 6715 | if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err); |
| 6683 | try sema.addComptimeReturnTypeNote(arg_block, func, func_src, ret_ty, sema.err.?, comptime_only_ret_ty); | | |
| 6684 | } | | |
| 6685 | return err; | 6716 | return err; |
| 6686 | }; | 6717 | }; |
| 6687 | switch (arg_val.tag()) { | 6718 | switch (arg_val.tag()) { |
| ... | @@ -10223,6 +10254,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10223,6 +10254,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10223 | .label = &label, | 10254 | .label = &label, |
| 10224 | .inlining = block.inlining, | 10255 | .inlining = block.inlining, |
| 10225 | .is_comptime = block.is_comptime, | 10256 | .is_comptime = block.is_comptime, |
| | 10257 | .comptime_reason = block.comptime_reason, |
| 10226 | .is_typeof = block.is_typeof, | 10258 | .is_typeof = block.is_typeof, |
| 10227 | .switch_else_err_ty = else_error_ty, | 10259 | .switch_else_err_ty = else_error_ty, |
| 10228 | .runtime_cond = block.runtime_cond, | 10260 | .runtime_cond = block.runtime_cond, |
| ... | @@ -10333,7 +10365,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10333,7 +10365,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10333 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); | 10365 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); |
| 10334 | } | 10366 | } |
| 10335 | | 10367 | |
| 10336 | try sema.requireRuntimeBlock(block, src, operand_src); | 10368 | if (child_block.is_comptime) { |
| | 10369 | _ = sema.resolveConstValue(&child_block, operand_src, operand, "condition in comptime switch must be comptime-known") catch |err| { |
| | 10370 | if (err == error.AnalysisFail and child_block.comptime_reason != null) try child_block.comptime_reason.?.explain(sema, sema.err); |
| | 10371 | return err; |
| | 10372 | }; |
| | 10373 | unreachable; |
| | 10374 | } |
| 10337 | | 10375 | |
| 10338 | const estimated_cases_extra = (scalar_cases_len + multi_cases_len) * | 10376 | const estimated_cases_extra = (scalar_cases_len + multi_cases_len) * |
| 10339 | @typeInfo(Air.SwitchBr.Case).Struct.fields.len + 2; | 10377 | @typeInfo(Air.SwitchBr.Case).Struct.fields.len + 2; |
| ... | @@ -21469,6 +21507,9 @@ fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: | ... | @@ -21469,6 +21507,9 @@ fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: |
| 21469 | if (runtime_src) |some| { | 21507 | if (runtime_src) |some| { |
| 21470 | try sema.errNote(block, some, msg, "operation is runtime due to this operand", .{}); | 21508 | try sema.errNote(block, some, msg, "operation is runtime due to this operand", .{}); |
| 21471 | } | 21509 | } |
| | 21510 | if (block.comptime_reason) |some| { |
| | 21511 | try some.explain(sema, msg); |
| | 21512 | } |
| 21472 | break :msg msg; | 21513 | break :msg msg; |
| 21473 | }; | 21514 | }; |
| 21474 | return sema.failWithOwnedErrorMsg(msg); | 21515 | return sema.failWithOwnedErrorMsg(msg); |
| ... | @@ -21940,6 +21981,7 @@ fn addSafetyCheck( | ... | @@ -21940,6 +21981,7 @@ fn addSafetyCheck( |
| 21940 | panic_id: PanicId, | 21981 | panic_id: PanicId, |
| 21941 | ) !void { | 21982 | ) !void { |
| 21942 | const gpa = sema.gpa; | 21983 | const gpa = sema.gpa; |
| | 21984 | assert(!parent_block.is_comptime); |
| 21943 | | 21985 | |
| 21944 | var fail_block: Block = .{ | 21986 | var fail_block: Block = .{ |
| 21945 | .parent = parent_block, | 21987 | .parent = parent_block, |
| ... | @@ -21949,7 +21991,7 @@ fn addSafetyCheck( | ... | @@ -21949,7 +21991,7 @@ fn addSafetyCheck( |
| 21949 | .wip_capture_scope = parent_block.wip_capture_scope, | 21991 | .wip_capture_scope = parent_block.wip_capture_scope, |
| 21950 | .instructions = .{}, | 21992 | .instructions = .{}, |
| 21951 | .inlining = parent_block.inlining, | 21993 | .inlining = parent_block.inlining, |
| 21952 | .is_comptime = parent_block.is_comptime, | 21994 | .is_comptime = false, |
| 21953 | }; | 21995 | }; |
| 21954 | | 21996 | |
| 21955 | defer fail_block.instructions.deinit(gpa); | 21997 | defer fail_block.instructions.deinit(gpa); |
| ... | @@ -22061,6 +22103,7 @@ fn panicUnwrapError( | ... | @@ -22061,6 +22103,7 @@ fn panicUnwrapError( |
| 22061 | unwrap_err_tag: Air.Inst.Tag, | 22103 | unwrap_err_tag: Air.Inst.Tag, |
| 22062 | is_non_err_tag: Air.Inst.Tag, | 22104 | is_non_err_tag: Air.Inst.Tag, |
| 22063 | ) !void { | 22105 | ) !void { |
| | 22106 | assert(!parent_block.is_comptime); |
| 22064 | const ok = try parent_block.addUnOp(is_non_err_tag, operand); | 22107 | const ok = try parent_block.addUnOp(is_non_err_tag, operand); |
| 22065 | const gpa = sema.gpa; | 22108 | const gpa = sema.gpa; |
| 22066 | | 22109 | |
| ... | @@ -22072,7 +22115,7 @@ fn panicUnwrapError( | ... | @@ -22072,7 +22115,7 @@ fn panicUnwrapError( |
| 22072 | .wip_capture_scope = parent_block.wip_capture_scope, | 22115 | .wip_capture_scope = parent_block.wip_capture_scope, |
| 22073 | .instructions = .{}, | 22116 | .instructions = .{}, |
| 22074 | .inlining = parent_block.inlining, | 22117 | .inlining = parent_block.inlining, |
| 22075 | .is_comptime = parent_block.is_comptime, | 22118 | .is_comptime = false, |
| 22076 | }; | 22119 | }; |
| 22077 | | 22120 | |
| 22078 | defer fail_block.instructions.deinit(gpa); | 22121 | defer fail_block.instructions.deinit(gpa); |
| ... | @@ -22104,6 +22147,7 @@ fn panicIndexOutOfBounds( | ... | @@ -22104,6 +22147,7 @@ fn panicIndexOutOfBounds( |
| 22104 | len: Air.Inst.Ref, | 22147 | len: Air.Inst.Ref, |
| 22105 | cmp_op: Air.Inst.Tag, | 22148 | cmp_op: Air.Inst.Tag, |
| 22106 | ) !void { | 22149 | ) !void { |
| | 22150 | assert(!parent_block.is_comptime); |
| 22107 | const ok = try parent_block.addBinOp(cmp_op, index, len); | 22151 | const ok = try parent_block.addBinOp(cmp_op, index, len); |
| 22108 | const gpa = sema.gpa; | 22152 | const gpa = sema.gpa; |
| 22109 | | 22153 | |
| ... | @@ -22115,7 +22159,7 @@ fn panicIndexOutOfBounds( | ... | @@ -22115,7 +22159,7 @@ fn panicIndexOutOfBounds( |
| 22115 | .wip_capture_scope = parent_block.wip_capture_scope, | 22159 | .wip_capture_scope = parent_block.wip_capture_scope, |
| 22116 | .instructions = .{}, | 22160 | .instructions = .{}, |
| 22117 | .inlining = parent_block.inlining, | 22161 | .inlining = parent_block.inlining, |
| 22118 | .is_comptime = parent_block.is_comptime, | 22162 | .is_comptime = false, |
| 22119 | }; | 22163 | }; |
| 22120 | | 22164 | |
| 22121 | defer fail_block.instructions.deinit(gpa); | 22165 | defer fail_block.instructions.deinit(gpa); |
| ... | @@ -22146,6 +22190,7 @@ fn panicSentinelMismatch( | ... | @@ -22146,6 +22190,7 @@ fn panicSentinelMismatch( |
| 22146 | ptr: Air.Inst.Ref, | 22190 | ptr: Air.Inst.Ref, |
| 22147 | sentinel_index: Air.Inst.Ref, | 22191 | sentinel_index: Air.Inst.Ref, |
| 22148 | ) !void { | 22192 | ) !void { |
| | 22193 | assert(!parent_block.is_comptime); |
| 22149 | const expected_sentinel_val = maybe_sentinel orelse return; | 22194 | const expected_sentinel_val = maybe_sentinel orelse return; |
| 22150 | const expected_sentinel = try sema.addConstant(sentinel_ty, expected_sentinel_val); | 22195 | const expected_sentinel = try sema.addConstant(sentinel_ty, expected_sentinel_val); |
| 22151 | | 22196 | |
| ... | @@ -22186,7 +22231,7 @@ fn panicSentinelMismatch( | ... | @@ -22186,7 +22231,7 @@ fn panicSentinelMismatch( |
| 22186 | .wip_capture_scope = parent_block.wip_capture_scope, | 22231 | .wip_capture_scope = parent_block.wip_capture_scope, |
| 22187 | .instructions = .{}, | 22232 | .instructions = .{}, |
| 22188 | .inlining = parent_block.inlining, | 22233 | .inlining = parent_block.inlining, |
| 22189 | .is_comptime = parent_block.is_comptime, | 22234 | .is_comptime = false, |
| 22190 | }; | 22235 | }; |
| 22191 | | 22236 | |
| 22192 | defer fail_block.instructions.deinit(gpa); | 22237 | defer fail_block.instructions.deinit(gpa); |