@@ -1495,7 +1495,8 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
1495
1495
1496
1496
// Finally, the last section of indexes refers to the map of ZIR=>AIR.
1497
1497
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;
1499
1500
return inst;
1500
1501
}
1501
1502
@@ -5570,11 +5571,15 @@ const GenericCallAdapter = struct {
5570
5571
generic_fn: *Module.Fn,
5571
5572
precomputed_hash: u64,
5572
5573
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,
5576
5575
module: *Module,
5577
5576
5577
+ const Arg = struct {
5578
+ ty: Type,
5579
+ val: Value,
5580
+ is_anytype: bool,
5581
+ };
5582
+
5578
5583
pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool {
5579
5584
_ = adapted_key;
5580
5585
// The generic function Decl is guaranteed to be the first dependency
@@ -5585,10 +5590,10 @@ const GenericCallAdapter = struct {
5585
5590
5586
5591
const other_comptime_args = other_key.comptime_args.?;
5587
5592
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];
5589
5594
const this_is_comptime = this_arg.val.tag() != .generic_poison;
5590
5595
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 ;
5592
5597
const other_is_anytype = other_key.isAnytypeParam(ctx.module, @intCast(u32, i));
5593
5598
5594
5599
if (other_is_anytype != this_is_anytype) return false;
@@ -5607,7 +5612,17 @@ const GenericCallAdapter = struct {
5607
5612
}
5608
5613
} else if (this_is_comptime) {
5609
5614
// 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) {
5611
5626
return false;
5612
5627
}
5613
5628
}
@@ -6258,8 +6273,7 @@ fn instantiateGenericCall(
6258
6273
var hasher = std.hash.Wyhash.init(0);
6259
6274
std.hash.autoHash(&hasher, @ptrToInt(module_fn));
6260
6275
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);
6263
6277
{
6264
6278
var i: usize = 0;
6265
6279
for (fn_info.param_body) |inst| {
@@ -6283,8 +6297,9 @@ fn instantiateGenericCall(
6283
6297
else => continue,
6284
6298
}
6285
6299
6300
+ const arg_ty = sema.typeOf(uncasted_args[i]);
6301
+
6286
6302
if (is_comptime) {
6287
- const arg_ty = sema.typeOf(uncasted_args[i]);
6288
6303
const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[i]) catch |err| switch (err) {
6289
6304
error.NeededSourceLocation => {
6290
6305
const decl = sema.mod.declPtr(block.src_decl);
@@ -6297,27 +6312,30 @@ fn instantiateGenericCall(
6297
6312
arg_val.hash(arg_ty, &hasher, mod);
6298
6313
if (is_anytype) {
6299
6314
arg_ty.hashWithHasher(&hasher, mod);
6300
- comptime_tvs [i] = .{
6315
+ generic_args [i] = .{
6301
6316
.ty = arg_ty,
6302
6317
.val = arg_val,
6318
+ .is_anytype = true,
6303
6319
};
6304
6320
} else {
6305
- comptime_tvs [i] = .{
6306
- .ty = Type.initTag(.generic_poison) ,
6321
+ generic_args [i] = .{
6322
+ .ty = arg_ty ,
6307
6323
.val = arg_val,
6324
+ .is_anytype = false,
6308
6325
};
6309
6326
}
6310
6327
} else if (is_anytype) {
6311
- const arg_ty = sema.typeOf(uncasted_args[i]);
6312
6328
arg_ty.hashWithHasher(&hasher, mod);
6313
- comptime_tvs [i] = .{
6329
+ generic_args [i] = .{
6314
6330
.ty = arg_ty,
6315
6331
.val = Value.initTag(.generic_poison),
6332
+ .is_anytype = true,
6316
6333
};
6317
6334
} else {
6318
- comptime_tvs [i] = .{
6319
- .ty = Type.initTag(.generic_poison) ,
6335
+ generic_args [i] = .{
6336
+ .ty = arg_ty ,
6320
6337
.val = Value.initTag(.generic_poison),
6338
+ .is_anytype = false,
6321
6339
};
6322
6340
}
6323
6341
@@ -6331,7 +6349,7 @@ fn instantiateGenericCall(
6331
6349
.generic_fn = module_fn,
6332
6350
.precomputed_hash = precomputed_hash,
6333
6351
.func_ty_info = func_ty_info,
6334
- .comptime_tvs = comptime_tvs ,
6352
+ .args = generic_args ,
6335
6353
.module = mod,
6336
6354
};
6337
6355
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
11184
11202
const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs);
11185
11203
const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs);
11186
11204
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
+
11187
11220
// TODO: emit compile error when .div is used on integers and there would be an
11188
11221
// ambiguous result between div_floor and div_trunc.
11189
11222
@@ -30124,7 +30157,7 @@ fn valuesEqual(
30124
30157
rhs: Value,
30125
30158
ty: Type,
30126
30159
) 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));
30128
30161
}
30129
30162
30130
30163
/// Asserts the values are comparable vectors of type `ty`.
0 commit comments