@@ -1495,7 +1495,8 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
14951495
14961496 // Finally, the last section of indexes refers to the map of ZIR=>AIR.
14971497 const inst = sema.inst_map.get(@intCast(u32, i)).?;
1498- if (sema.typeOf(inst).tag() == .generic_poison) return error.GenericPoison;
1498+ const ty = sema.typeOf(inst);
1499+ if (ty.tag() == .generic_poison) return error.GenericPoison;
14991500 return inst;
15001501}
15011502
@@ -5570,11 +5571,15 @@ const GenericCallAdapter = struct {
55705571 generic_fn: *Module.Fn,
55715572 precomputed_hash: u64,
55725573 func_ty_info: Type.Payload.Function.Data,
5573- /// Unlike comptime_args, the Type here is not always present.
5574- /// .generic_poison is used to communicate non-anytype parameters.
5575- comptime_tvs: []const TypedValue,
5574+ args: []const Arg,
55765575 module: *Module,
55775576
5577+ const Arg = struct {
5578+ ty: Type,
5579+ val: Value,
5580+ is_anytype: bool,
5581+ };
5582+
55785583 pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool {
55795584 _ = adapted_key;
55805585 // The generic function Decl is guaranteed to be the first dependency
@@ -5585,10 +5590,10 @@ const GenericCallAdapter = struct {
55855590
55865591 const other_comptime_args = other_key.comptime_args.?;
55875592 for (other_comptime_args[0..ctx.func_ty_info.param_types.len]) |other_arg, i| {
5588- const this_arg = ctx.comptime_tvs [i];
5593+ const this_arg = ctx.args [i];
55895594 const this_is_comptime = this_arg.val.tag() != .generic_poison;
55905595 const other_is_comptime = other_arg.val.tag() != .generic_poison;
5591- const this_is_anytype = this_arg.ty.tag() != .generic_poison ;
5596+ const this_is_anytype = this_arg.is_anytype ;
55925597 const other_is_anytype = other_key.isAnytypeParam(ctx.module, @intCast(u32, i));
55935598
55945599 if (other_is_anytype != this_is_anytype) return false;
@@ -5607,7 +5612,17 @@ const GenericCallAdapter = struct {
56075612 }
56085613 } else if (this_is_comptime) {
56095614 // Both are comptime parameters but not anytype parameters.
5610- if (!this_arg.val.eql(other_arg.val, other_arg.ty, ctx.module)) {
5615+ // We assert no error is possible here because any lazy values must be resolved
5616+ // before inserting into the generic function hash map.
5617+ const is_eql = Value.eqlAdvanced(
5618+ this_arg.val,
5619+ this_arg.ty,
5620+ other_arg.val,
5621+ other_arg.ty,
5622+ ctx.module,
5623+ null,
5624+ ) catch unreachable;
5625+ if (!is_eql) {
56115626 return false;
56125627 }
56135628 }
@@ -6258,8 +6273,7 @@ fn instantiateGenericCall(
62586273 var hasher = std.hash.Wyhash.init(0);
62596274 std.hash.autoHash(&hasher, @ptrToInt(module_fn));
62606275
6261- const comptime_tvs = try sema.arena.alloc(TypedValue, func_ty_info.param_types.len);
6262-
6276+ const generic_args = try sema.arena.alloc(GenericCallAdapter.Arg, func_ty_info.param_types.len);
62636277 {
62646278 var i: usize = 0;
62656279 for (fn_info.param_body) |inst| {
@@ -6283,8 +6297,9 @@ fn instantiateGenericCall(
62836297 else => continue,
62846298 }
62856299
6300+ const arg_ty = sema.typeOf(uncasted_args[i]);
6301+
62866302 if (is_comptime) {
6287- const arg_ty = sema.typeOf(uncasted_args[i]);
62886303 const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[i]) catch |err| switch (err) {
62896304 error.NeededSourceLocation => {
62906305 const decl = sema.mod.declPtr(block.src_decl);
@@ -6297,27 +6312,30 @@ fn instantiateGenericCall(
62976312 arg_val.hash(arg_ty, &hasher, mod);
62986313 if (is_anytype) {
62996314 arg_ty.hashWithHasher(&hasher, mod);
6300- comptime_tvs [i] = .{
6315+ generic_args [i] = .{
63016316 .ty = arg_ty,
63026317 .val = arg_val,
6318+ .is_anytype = true,
63036319 };
63046320 } else {
6305- comptime_tvs [i] = .{
6306- .ty = Type.initTag(.generic_poison) ,
6321+ generic_args [i] = .{
6322+ .ty = arg_ty ,
63076323 .val = arg_val,
6324+ .is_anytype = false,
63086325 };
63096326 }
63106327 } else if (is_anytype) {
6311- const arg_ty = sema.typeOf(uncasted_args[i]);
63126328 arg_ty.hashWithHasher(&hasher, mod);
6313- comptime_tvs [i] = .{
6329+ generic_args [i] = .{
63146330 .ty = arg_ty,
63156331 .val = Value.initTag(.generic_poison),
6332+ .is_anytype = true,
63166333 };
63176334 } else {
6318- comptime_tvs [i] = .{
6319- .ty = Type.initTag(.generic_poison) ,
6335+ generic_args [i] = .{
6336+ .ty = arg_ty ,
63206337 .val = Value.initTag(.generic_poison),
6338+ .is_anytype = false,
63216339 };
63226340 }
63236341
@@ -6331,7 +6349,7 @@ fn instantiateGenericCall(
63316349 .generic_fn = module_fn,
63326350 .precomputed_hash = precomputed_hash,
63336351 .func_ty_info = func_ty_info,
6334- .comptime_tvs = comptime_tvs ,
6352+ .args = generic_args ,
63356353 .module = mod,
63366354 };
63376355 const gop = try mod.monomorphed_funcs.getOrPutAdapted(gpa, {}, adapter);
@@ -11184,6 +11202,21 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1118411202 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs);
1118511203 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs);
1118611204
11205+ if ((lhs_ty.zigTypeTag() == .ComptimeFloat and rhs_ty.zigTypeTag() == .ComptimeInt) or
11206+ (lhs_ty.zigTypeTag() == .ComptimeInt and rhs_ty.zigTypeTag() == .ComptimeFloat))
11207+ {
11208+ // If it makes a difference whether we coerce to ints or floats before doing the division, error.
11209+ // If lhs % rhs is 0, it doesn't matter.
11210+ const lhs_val = maybe_lhs_val orelse unreachable;
11211+ const rhs_val = maybe_rhs_val orelse unreachable;
11212+ const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, target) catch unreachable;
11213+ if (rem.compareWithZero(.neq)) {
11214+ return sema.fail(block, src, "ambiguous coercion of division operands '{s}' and '{s}'; non-zero remainder '{}'", .{
11215+ @tagName(lhs_ty.tag()), @tagName(rhs_ty.tag()), rem.fmtValue(resolved_type, sema.mod),
11216+ });
11217+ }
11218+ }
11219+
1118711220 // TODO: emit compile error when .div is used on integers and there would be an
1118811221 // ambiguous result between div_floor and div_trunc.
1118911222
@@ -30124,7 +30157,7 @@ fn valuesEqual(
3012430157 rhs: Value,
3012530158 ty: Type,
3012630159) CompileError!bool {
30127- return Value.eqlAdvanced(lhs, rhs, ty, sema.mod, sema.kit(block, src));
30160+ return Value.eqlAdvanced(lhs, ty, rhs, ty, sema.mod, sema.kit(block, src));
3012830161}
3012930162
3013030163/// Asserts the values are comparable vectors of type `ty`.
0 commit comments