| ... | @@ -63,6 +63,13 @@ comptime_args: []InternPool.Index = &.{}, | ... | @@ -63,6 +63,13 @@ comptime_args: []InternPool.Index = &.{}, |
| 63 | /// Used to communicate from a generic function instantiation to the logic that | 63 | /// Used to communicate from a generic function instantiation to the logic that |
| 64 | /// creates a generic function instantiation value in `funcCommon`. | 64 | /// creates a generic function instantiation value in `funcCommon`. |
| 65 | generic_owner: InternPool.Index = .none, | 65 | generic_owner: InternPool.Index = .none, |
| | 66 | /// When `generic_owner` is not none, this contains the generic function |
| | 67 | /// instantiation callsite so that compile errors on the parameter types of the |
| | 68 | /// instantiation can point back to the instantiation site in addition to the |
| | 69 | /// declaration site. |
| | 70 | generic_call_src: LazySrcLoc = .unneeded, |
| | 71 | /// Corresponds to `generic_call_src`. |
| | 72 | generic_call_decl: Decl.OptionalIndex = .none, |
| 66 | /// The key is types that must be fully resolved prior to machine code | 73 | /// The key is types that must be fully resolved prior to machine code |
| 67 | /// generation pass. Types are added to this set when resolving them | 74 | /// generation pass. Types are added to this set when resolving them |
| 68 | /// immediately could cause a dependency loop, but they do need to be resolved | 75 | /// immediately could cause a dependency loop, but they do need to be resolved |
| ... | @@ -2055,10 +2062,7 @@ fn resolveDefinedValue( | ... | @@ -2055,10 +2062,7 @@ fn resolveDefinedValue( |
| 2055 | /// Value Tag `variable` causes this function to return `null`. | 2062 | /// Value Tag `variable` causes this function to return `null`. |
| 2056 | /// Value Tag `undef` causes this function to return the Value. | 2063 | /// Value Tag `undef` causes this function to return the Value. |
| 2057 | /// Value Tag `generic_poison` causes `error.GenericPoison` to be returned. | 2064 | /// Value Tag `generic_poison` causes `error.GenericPoison` to be returned. |
| 2058 | fn resolveMaybeUndefVal( | 2065 | fn resolveMaybeUndefVal(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { |
| 2059 | sema: *Sema, | | |
| 2060 | inst: Air.Inst.Ref, | | |
| 2061 | ) CompileError!?Value { | | |
| 2062 | const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null; | 2066 | const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null; |
| 2063 | if (val.isGenericPoison()) return error.GenericPoison; | 2067 | if (val.isGenericPoison()) return error.GenericPoison; |
| 2064 | if (val.ip_index != .none and sema.mod.intern_pool.isVariable(val.toIntern())) return null; | 2068 | if (val.ip_index != .none and sema.mod.intern_pool.isVariable(val.toIntern())) return null; |
| ... | @@ -2069,10 +2073,7 @@ fn resolveMaybeUndefVal( | ... | @@ -2069,10 +2073,7 @@ fn resolveMaybeUndefVal( |
| 2069 | /// Value Tag `undef` causes this function to return the Value. | 2073 | /// Value Tag `undef` causes this function to return the Value. |
| 2070 | /// Value Tag `generic_poison` causes `error.GenericPoison` to be returned. | 2074 | /// Value Tag `generic_poison` causes `error.GenericPoison` to be returned. |
| 2071 | /// Lazy values are recursively resolved. | 2075 | /// Lazy values are recursively resolved. |
| 2072 | fn resolveMaybeUndefLazyVal( | 2076 | fn resolveMaybeUndefLazyVal(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { |
| 2073 | sema: *Sema, | | |
| 2074 | inst: Air.Inst.Ref, | | |
| 2075 | ) CompileError!?Value { | | |
| 2076 | return try sema.resolveLazyValue((try sema.resolveMaybeUndefVal(inst)) orelse return null); | 2077 | return try sema.resolveLazyValue((try sema.resolveMaybeUndefVal(inst)) orelse return null); |
| 2077 | } | 2078 | } |
| 2078 | | 2079 | |
| ... | @@ -2081,10 +2082,7 @@ fn resolveMaybeUndefLazyVal( | ... | @@ -2081,10 +2082,7 @@ fn resolveMaybeUndefLazyVal( |
| 2081 | /// Value Tag `generic_poison` causes `error.GenericPoison` to be returned. | 2082 | /// Value Tag `generic_poison` causes `error.GenericPoison` to be returned. |
| 2082 | /// Value Tag `decl_ref` and `decl_ref_mut` or any nested such value results in `null`. | 2083 | /// Value Tag `decl_ref` and `decl_ref_mut` or any nested such value results in `null`. |
| 2083 | /// Lazy values are recursively resolved. | 2084 | /// Lazy values are recursively resolved. |
| 2084 | fn resolveMaybeUndefValIntable( | 2085 | fn resolveMaybeUndefValIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { |
| 2085 | sema: *Sema, | | |
| 2086 | inst: Air.Inst.Ref, | | |
| 2087 | ) CompileError!?Value { | | |
| 2088 | const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null; | 2086 | const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null; |
| 2089 | if (val.isGenericPoison()) return error.GenericPoison; | 2087 | if (val.isGenericPoison()) return error.GenericPoison; |
| 2090 | if (val.ip_index == .none) return val; | 2088 | if (val.ip_index == .none) return val; |
| ... | @@ -7047,12 +7045,18 @@ fn analyzeCall( | ... | @@ -7047,12 +7045,18 @@ fn analyzeCall( |
| 7047 | const parent_fn_ret_ty = sema.fn_ret_ty; | 7045 | const parent_fn_ret_ty = sema.fn_ret_ty; |
| 7048 | const parent_fn_ret_ty_ies = sema.fn_ret_ty_ies; | 7046 | const parent_fn_ret_ty_ies = sema.fn_ret_ty_ies; |
| 7049 | const parent_generic_owner = sema.generic_owner; | 7047 | const parent_generic_owner = sema.generic_owner; |
| | 7048 | const parent_generic_call_src = sema.generic_call_src; |
| | 7049 | const parent_generic_call_decl = sema.generic_call_decl; |
| 7050 | sema.fn_ret_ty = bare_return_type; | 7050 | sema.fn_ret_ty = bare_return_type; |
| 7051 | sema.fn_ret_ty_ies = null; | 7051 | sema.fn_ret_ty_ies = null; |
| 7052 | sema.generic_owner = .none; | 7052 | sema.generic_owner = .none; |
| | 7053 | sema.generic_call_src = .unneeded; |
| | 7054 | sema.generic_call_decl = .none; |
| 7053 | defer sema.fn_ret_ty = parent_fn_ret_ty; | 7055 | defer sema.fn_ret_ty = parent_fn_ret_ty; |
| 7054 | defer sema.fn_ret_ty_ies = parent_fn_ret_ty_ies; | 7056 | defer sema.fn_ret_ty_ies = parent_fn_ret_ty_ies; |
| 7055 | defer sema.generic_owner = parent_generic_owner; | 7057 | defer sema.generic_owner = parent_generic_owner; |
| | 7058 | defer sema.generic_call_src = parent_generic_call_src; |
| | 7059 | defer sema.generic_call_decl = parent_generic_call_decl; |
| 7056 | | 7060 | |
| 7057 | if (module_fn.analysis(ip).inferred_error_set) { | 7061 | if (module_fn.analysis(ip).inferred_error_set) { |
| 7058 | // Create a fresh inferred error set type for inline/comptime calls. | 7062 | // Create a fresh inferred error set type for inline/comptime calls. |
| ... | @@ -7506,6 +7510,8 @@ fn instantiateGenericCall( | ... | @@ -7506,6 +7510,8 @@ fn instantiateGenericCall( |
| 7506 | .owner_func_index = .none, | 7510 | .owner_func_index = .none, |
| 7507 | .comptime_args = comptime_args, | 7511 | .comptime_args = comptime_args, |
| 7508 | .generic_owner = generic_owner, | 7512 | .generic_owner = generic_owner, |
| | 7513 | .generic_call_src = call_src, |
| | 7514 | .generic_call_decl = block.src_decl.toOptional(), |
| 7509 | .branch_quota = sema.branch_quota, | 7515 | .branch_quota = sema.branch_quota, |
| 7510 | .branch_count = sema.branch_count, | 7516 | .branch_count = sema.branch_count, |
| 7511 | .comptime_mutable_decls = sema.comptime_mutable_decls, | 7517 | .comptime_mutable_decls = sema.comptime_mutable_decls, |
| ... | @@ -9167,13 +9173,19 @@ fn zirParam( | ... | @@ -9167,13 +9173,19 @@ fn zirParam( |
| 9167 | const prev_params = block.params; | 9173 | const prev_params = block.params; |
| 9168 | const prev_no_partial_func_type = sema.no_partial_func_ty; | 9174 | const prev_no_partial_func_type = sema.no_partial_func_ty; |
| 9169 | const prev_generic_owner = sema.generic_owner; | 9175 | const prev_generic_owner = sema.generic_owner; |
| | 9176 | const prev_generic_call_src = sema.generic_call_src; |
| | 9177 | const prev_generic_call_decl = sema.generic_call_decl; |
| 9170 | block.params = .{}; | 9178 | block.params = .{}; |
| 9171 | sema.no_partial_func_ty = true; | 9179 | sema.no_partial_func_ty = true; |
| 9172 | sema.generic_owner = .none; | 9180 | sema.generic_owner = .none; |
| | 9181 | sema.generic_call_src = .unneeded; |
| | 9182 | sema.generic_call_decl = .none; |
| 9173 | defer { | 9183 | defer { |
| 9174 | block.params = prev_params; | 9184 | block.params = prev_params; |
| 9175 | sema.no_partial_func_ty = prev_no_partial_func_type; | 9185 | sema.no_partial_func_ty = prev_no_partial_func_type; |
| 9176 | sema.generic_owner = prev_generic_owner; | 9186 | sema.generic_owner = prev_generic_owner; |
| | 9187 | sema.generic_call_src = prev_generic_call_src; |
| | 9188 | sema.generic_call_decl = prev_generic_call_decl; |
| 9177 | } | 9189 | } |
| 9178 | | 9190 | |
| 9179 | if (sema.resolveBody(block, body, inst)) |param_ty_inst| { | 9191 | if (sema.resolveBody(block, body, inst)) |param_ty_inst| { |
| ... | @@ -9289,6 +9301,8 @@ fn zirParamAnytype( | ... | @@ -9289,6 +9301,8 @@ fn zirParamAnytype( |
| 9289 | param_index: u32, | 9301 | param_index: u32, |
| 9290 | comptime_syntax: bool, | 9302 | comptime_syntax: bool, |
| 9291 | ) CompileError!void { | 9303 | ) CompileError!void { |
| | 9304 | const mod = sema.mod; |
| | 9305 | const gpa = sema.gpa; |
| 9292 | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; | 9306 | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; |
| 9293 | const param_name: Zir.NullTerminatedString = @enumFromInt(inst_data.start); | 9307 | const param_name: Zir.NullTerminatedString = @enumFromInt(inst_data.start); |
| 9294 | const src = inst_data.src(); | 9308 | const src = inst_data.src(); |
| ... | @@ -9301,13 +9315,68 @@ fn zirParamAnytype( | ... | @@ -9301,13 +9315,68 @@ fn zirParamAnytype( |
| 9301 | sema.comptime_args[param_index] = opv.toIntern(); | 9315 | sema.comptime_args[param_index] = opv.toIntern(); |
| 9302 | return; | 9316 | return; |
| 9303 | } | 9317 | } |
| | 9318 | const arg_src: LazySrcLoc = if (sema.generic_call_src == .node_offset) .{ .call_arg = .{ |
| | 9319 | .call_node_offset = sema.generic_call_src.node_offset.x, |
| | 9320 | .arg_index = param_index, |
| | 9321 | } } else .unneeded; |
| | 9322 | |
| 9304 | if (comptime_syntax) { | 9323 | if (comptime_syntax) { |
| 9305 | sema.comptime_args[param_index] = (try sema.resolveConstMaybeUndefVal(block, src, air_ref, "parameter is declared comptime")).toIntern(); | 9324 | if (try sema.resolveMaybeUndefVal(air_ref)) |val| { |
| 9306 | return; | 9325 | sema.comptime_args[param_index] = val.toIntern(); |
| | 9326 | return; |
| | 9327 | } |
| | 9328 | const msg = msg: { |
| | 9329 | const fallback_src = src.toSrcLoc(mod.declPtr(block.src_decl), mod); |
| | 9330 | const src_loc = if (sema.generic_call_decl.unwrap()) |decl| |
| | 9331 | if (arg_src != .unneeded) |
| | 9332 | arg_src.toSrcLoc(mod.declPtr(decl), mod) |
| | 9333 | else |
| | 9334 | fallback_src |
| | 9335 | else |
| | 9336 | fallback_src; |
| | 9337 | |
| | 9338 | const msg = try Module.ErrorMsg.create(gpa, src_loc, "{s}", .{ |
| | 9339 | @as([]const u8, "runtime-known argument passed to comptime parameter"), |
| | 9340 | }); |
| | 9341 | errdefer msg.destroy(gpa); |
| | 9342 | |
| | 9343 | if (sema.generic_call_decl != .none) { |
| | 9344 | try sema.errNote(block, src, msg, "{s}", .{@as([]const u8, "declared here")}); |
| | 9345 | } |
| | 9346 | break :msg msg; |
| | 9347 | }; |
| | 9348 | return sema.failWithOwnedErrorMsg(msg); |
| 9307 | } | 9349 | } |
| | 9350 | |
| 9308 | if (try sema.typeRequiresComptime(param_ty)) { | 9351 | if (try sema.typeRequiresComptime(param_ty)) { |
| 9309 | sema.comptime_args[param_index] = (try sema.resolveConstMaybeUndefVal(block, src, air_ref, "parameter type requires comptime")).toIntern(); | 9352 | if (try sema.resolveMaybeUndefVal(air_ref)) |val| { |
| 9310 | return; | 9353 | sema.comptime_args[param_index] = val.toIntern(); |
| | 9354 | return; |
| | 9355 | } |
| | 9356 | const msg = msg: { |
| | 9357 | const fallback_src = src.toSrcLoc(mod.declPtr(block.src_decl), mod); |
| | 9358 | const src_loc = if (sema.generic_call_decl.unwrap()) |decl| |
| | 9359 | if (arg_src != .unneeded) |
| | 9360 | arg_src.toSrcLoc(mod.declPtr(decl), mod) |
| | 9361 | else |
| | 9362 | fallback_src |
| | 9363 | else |
| | 9364 | fallback_src; |
| | 9365 | |
| | 9366 | const msg = try Module.ErrorMsg.create(gpa, src_loc, "{s}", .{ |
| | 9367 | @as([]const u8, "runtime-known argument passed to comptime-only type parameter"), |
| | 9368 | }); |
| | 9369 | errdefer msg.destroy(gpa); |
| | 9370 | |
| | 9371 | if (sema.generic_call_decl != .none) { |
| | 9372 | try sema.errNote(block, src, msg, "{s}", .{@as([]const u8, "declared here")}); |
| | 9373 | } |
| | 9374 | |
| | 9375 | try sema.explainWhyTypeIsComptime(msg, src_loc, param_ty); |
| | 9376 | |
| | 9377 | break :msg msg; |
| | 9378 | }; |
| | 9379 | return sema.failWithOwnedErrorMsg(msg); |
| 9311 | } | 9380 | } |
| 9312 | | 9381 | |
| 9313 | // The parameter is runtime-known. | 9382 | // The parameter is runtime-known. |