authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-30 02:18:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:57-07:00
logd0cd1c89da5d688634cdcd3fd645799b14553660
treef0b47c875ac351024fc349feaf0c1f78522608ba
parent61978c8c9473bc06fa1fde75e37374dd330ed614

Sema: port lazy value usage to be InternPool aware


1 files changed, 187 insertions(+), 73 deletions(-)

src/Sema.zig+187-73
...@@ -1915,6 +1915,18 @@ fn resolveConstValue(...@@ -1915,6 +1915,18 @@ fn resolveConstValue(
1915 return sema.failWithNeededComptime(block, src, reason);1915 return sema.failWithNeededComptime(block, src, reason);
1916}1916}
19171917
1918/// Will not return Value Tags: `variable`, `undef`. Instead they will emit compile errors.
1919/// Lazy values are recursively resolved.
1920fn resolveConstLazyValue(
1921 sema: *Sema,
1922 block: *Block,
1923 src: LazySrcLoc,
1924 air_ref: Air.Inst.Ref,
1925 reason: []const u8,
1926) CompileError!Value {
1927 return sema.resolveLazyValue(try sema.resolveConstValue(block, src, air_ref, reason));
1928}
1929
1918/// Value Tag `variable` causes this function to return `null`.1930/// Value Tag `variable` causes this function to return `null`.
1919/// Value Tag `undef` causes this function to return a compile error.1931/// Value Tag `undef` causes this function to return a compile error.
1920fn resolveDefinedValue(1932fn resolveDefinedValue(
...@@ -1952,10 +1964,22 @@ fn resolveMaybeUndefVal(...@@ -1952,10 +1964,22 @@ fn resolveMaybeUndefVal(
1952 }1964 }
1953}1965}
19541966
1967/// Value Tag `variable` causes this function to return `null`.
1968/// Value Tag `undef` causes this function to return the Value.
1969/// Value Tag `generic_poison` causes `error.GenericPoison` to be returned.
1970/// Lazy values are recursively resolved.
1971fn resolveMaybeUndefLazyVal(
1972 sema: *Sema,
1973 inst: Air.Inst.Ref,
1974) CompileError!?Value {
1975 return try sema.resolveLazyValue((try sema.resolveMaybeUndefVal(inst)) orelse return null);
1976}
1977
1955/// Value Tag `variable` results in `null`.1978/// Value Tag `variable` results in `null`.
1956/// Value Tag `undef` results in the Value.1979/// Value Tag `undef` results in the Value.
1957/// Value Tag `generic_poison` causes `error.GenericPoison` to be returned.1980/// Value Tag `generic_poison` causes `error.GenericPoison` to be returned.
1958/// Value Tag `decl_ref` and `decl_ref_mut` or any nested such value results in `null`.1981/// Value Tag `decl_ref` and `decl_ref_mut` or any nested such value results in `null`.
1982/// Lazy values are recursively resolved.
1959fn resolveMaybeUndefValIntable(1983fn resolveMaybeUndefValIntable(
1960 sema: *Sema,1984 sema: *Sema,
1961 inst: Air.Inst.Ref,1985 inst: Air.Inst.Ref,
...@@ -1976,8 +2000,7 @@ fn resolveMaybeUndefValIntable(...@@ -1976,8 +2000,7 @@ fn resolveMaybeUndefValIntable(
1976 else => break,2000 else => break,
1977 },2001 },
1978 };2002 };
1979 try sema.resolveLazyValue(val);2003 return try sema.resolveLazyValue(val);
1980 return val;
1981}2004}
19822005
1983/// Returns all Value tags including `variable` and `undef`.2006/// Returns all Value tags including `variable` and `undef`.
...@@ -5257,8 +5280,7 @@ fn zirCompileLog(...@@ -5257,8 +5280,7 @@ fn zirCompileLog(
52575280
5258 const arg = try sema.resolveInst(arg_ref);5281 const arg = try sema.resolveInst(arg_ref);
5259 const arg_ty = sema.typeOf(arg);5282 const arg_ty = sema.typeOf(arg);
5260 if (try sema.resolveMaybeUndefVal(arg)) |val| {5283 if (try sema.resolveMaybeUndefLazyVal(arg)) |val| {
5261 try sema.resolveLazyValue(val);
5262 try writer.print("@as({}, {})", .{5284 try writer.print("@as({}, {})", .{
5263 arg_ty.fmt(sema.mod), val.fmtValue(arg_ty, sema.mod),5285 arg_ty.fmt(sema.mod), val.fmtValue(arg_ty, sema.mod),
5264 });5286 });
...@@ -7266,15 +7288,14 @@ fn analyzeInlineCallArg(...@@ -7266,15 +7288,14 @@ fn analyzeInlineCallArg(
7266 // parameter or return type.7288 // parameter or return type.
7267 return error.GenericPoison;7289 return error.GenericPoison;
7268 },7290 },
7269 else => {7291 else => {},
7270 // Needed so that lazy values do not trigger
7271 // assertion due to type not being resolved
7272 // when the hash function is called.
7273 try sema.resolveLazyValue(arg_val);
7274 },
7275 }7292 }
7276 should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState(mod);7293 // Needed so that lazy values do not trigger
7277 memoized_arg_values[arg_i.*] = try arg_val.intern(param_ty.toType(), mod);7294 // assertion due to type not being resolved
7295 // when the hash function is called.
7296 const resolved_arg_val = try sema.resolveLazyValue(arg_val);
7297 should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod);
7298 memoized_arg_values[arg_i.*] = try resolved_arg_val.intern(param_ty.toType(), mod);
7278 } else {7299 } else {
7279 sema.inst_map.putAssumeCapacityNoClobber(inst, casted_arg);7300 sema.inst_map.putAssumeCapacityNoClobber(inst, casted_arg);
7280 }7301 }
...@@ -7302,15 +7323,14 @@ fn analyzeInlineCallArg(...@@ -7302,15 +7323,14 @@ fn analyzeInlineCallArg(
7302 // parameter or return type.7323 // parameter or return type.
7303 return error.GenericPoison;7324 return error.GenericPoison;
7304 },7325 },
7305 else => {7326 else => {},
7306 // Needed so that lazy values do not trigger
7307 // assertion due to type not being resolved
7308 // when the hash function is called.
7309 try sema.resolveLazyValue(arg_val);
7310 },
7311 }7327 }
7312 should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState(mod);7328 // Needed so that lazy values do not trigger
7313 memoized_arg_values[arg_i.*] = try arg_val.intern(sema.typeOf(uncasted_arg), mod);7329 // assertion due to type not being resolved
7330 // when the hash function is called.
7331 const resolved_arg_val = try sema.resolveLazyValue(arg_val);
7332 should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod);
7333 memoized_arg_values[arg_i.*] = try resolved_arg_val.intern(sema.typeOf(uncasted_arg), mod);
7314 } else {7334 } else {
7315 if (zir_tags[inst] == .param_anytype_comptime) {7335 if (zir_tags[inst] == .param_anytype_comptime) {
7316 _ = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "parameter is comptime");7336 _ = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "parameter is comptime");
...@@ -7369,9 +7389,7 @@ fn analyzeGenericCallArg(...@@ -7369,9 +7389,7 @@ fn analyzeGenericCallArg(
7369}7389}
73707390
7371fn analyzeGenericCallArgVal(sema: *Sema, block: *Block, arg_src: LazySrcLoc, uncasted_arg: Air.Inst.Ref) !Value {7391fn analyzeGenericCallArgVal(sema: *Sema, block: *Block, arg_src: LazySrcLoc, uncasted_arg: Air.Inst.Ref) !Value {
7372 const arg_val = try sema.resolveValue(block, arg_src, uncasted_arg, "parameter is comptime");7392 return sema.resolveLazyValue(try sema.resolveValue(block, arg_src, uncasted_arg, "parameter is comptime"));
7373 try sema.resolveLazyValue(arg_val);
7374 return arg_val;
7375}7393}
73767394
7377fn instantiateGenericCall(7395fn instantiateGenericCall(
...@@ -7903,7 +7921,8 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type)...@@ -7903,7 +7921,8 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type)
7903 for (tuple.types, tuple.values) |field_ty, field_val| {7921 for (tuple.types, tuple.values) |field_ty, field_val| {
7904 try sema.resolveTupleLazyValues(block, src, field_ty.toType());7922 try sema.resolveTupleLazyValues(block, src, field_ty.toType());
7905 if (field_val == .none) continue;7923 if (field_val == .none) continue;
7906 try sema.resolveLazyValue(field_val.toValue());7924 // TODO: mutate in intern pool
7925 _ = try sema.resolveLazyValue(field_val.toValue());
7907 }7926 }
7908}7927}
79097928
...@@ -10104,8 +10123,9 @@ fn zirSwitchCapture(...@@ -10104,8 +10123,9 @@ fn zirSwitchCapture(
1010410123
10105 if (block.inline_case_capture != .none) {10124 if (block.inline_case_capture != .none) {
10106 const item_val = sema.resolveConstValue(block, .unneeded, block.inline_case_capture, undefined) catch unreachable;10125 const item_val = sema.resolveConstValue(block, .unneeded, block.inline_case_capture, undefined) catch unreachable;
10126 const resolved_item_val = try sema.resolveLazyValue(item_val);
10107 if (operand_ty.zigTypeTag(mod) == .Union) {10127 if (operand_ty.zigTypeTag(mod) == .Union) {
10108 const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, sema.mod).?);10128 const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(resolved_item_val, sema.mod).?);
10109 const union_obj = mod.typeToUnion(operand_ty).?;10129 const union_obj = mod.typeToUnion(operand_ty).?;
10110 const field_ty = union_obj.fields.values()[field_index].ty;10130 const field_ty = union_obj.fields.values()[field_index].ty;
10111 if (try sema.resolveDefinedValue(block, sema.src, operand_ptr)) |union_val| {10131 if (try sema.resolveDefinedValue(block, sema.src, operand_ptr)) |union_val| {
...@@ -10141,7 +10161,7 @@ fn zirSwitchCapture(...@@ -10141,7 +10161,7 @@ fn zirSwitchCapture(
10141 return block.addStructFieldVal(operand_ptr, field_index, field_ty);10161 return block.addStructFieldVal(operand_ptr, field_index, field_ty);
10142 }10162 }
10143 } else if (is_ref) {10163 } else if (is_ref) {
10144 return sema.addConstantMaybeRef(block, operand_ty, item_val, true);10164 return sema.addConstantMaybeRef(block, operand_ty, resolved_item_val, true);
10145 } else {10165 } else {
10146 return block.inline_case_capture;10166 return block.inline_case_capture;
10147 }10167 }
...@@ -10249,7 +10269,7 @@ fn zirSwitchCapture(...@@ -10249,7 +10269,7 @@ fn zirSwitchCapture(
10249 for (items) |item| {10269 for (items) |item| {
10250 const item_ref = try sema.resolveInst(item);10270 const item_ref = try sema.resolveInst(item);
10251 // Previous switch validation ensured this will succeed10271 // Previous switch validation ensured this will succeed
10252 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;10272 const item_val = sema.resolveConstLazyValue(block, .unneeded, item_ref, "") catch unreachable;
10253 const name_ip = try mod.intern_pool.getOrPutString(gpa, item_val.getError(mod).?);10273 const name_ip = try mod.intern_pool.getOrPutString(gpa, item_val.getError(mod).?);
10254 names.putAssumeCapacityNoClobber(name_ip, {});10274 names.putAssumeCapacityNoClobber(name_ip, {});
10255 }10275 }
...@@ -10259,7 +10279,7 @@ fn zirSwitchCapture(...@@ -10259,7 +10279,7 @@ fn zirSwitchCapture(
10259 } else {10279 } else {
10260 const item_ref = try sema.resolveInst(items[0]);10280 const item_ref = try sema.resolveInst(items[0]);
10261 // Previous switch validation ensured this will succeed10281 // Previous switch validation ensured this will succeed
10262 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;10282 const item_val = sema.resolveConstLazyValue(block, .unneeded, item_ref, "") catch unreachable;
1026310283
10264 const item_ty = try mod.singleErrorSetType(item_val.getError(mod).?);10284 const item_ty = try mod.singleErrorSetType(item_val.getError(mod).?);
10265 return sema.bitCast(block, item_ty, operand, operand_src, null);10285 return sema.bitCast(block, item_ty, operand, operand_src, null);
...@@ -10993,6 +11013,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10993,6 +11013,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10993 defer merges.deinit(gpa);11013 defer merges.deinit(gpa);
1099411014
10995 if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| {11015 if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| {
11016 const resolved_operand_val = try sema.resolveLazyValue(operand_val);
10996 var extra_index: usize = special.end;11017 var extra_index: usize = special.end;
10997 {11018 {
10998 var scalar_i: usize = 0;11019 var scalar_i: usize = 0;
...@@ -11007,8 +11028,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11007,8 +11028,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1100711028
11008 const item = try sema.resolveInst(item_ref);11029 const item = try sema.resolveInst(item_ref);
11009 // Validation above ensured these will succeed.11030 // Validation above ensured these will succeed.
11010 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable;11031 const item_val = sema.resolveConstLazyValue(&child_block, .unneeded, item, "") catch unreachable;
11011 if (operand_val.eql(item_val, operand_ty, mod)) {11032 if (resolved_operand_val.eql(item_val, operand_ty, mod)) {
11012 if (is_inline) child_block.inline_case_capture = operand;11033 if (is_inline) child_block.inline_case_capture = operand;
1101311034
11014 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);11035 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);
...@@ -11033,8 +11054,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11033,8 +11054,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11033 for (items) |item_ref| {11054 for (items) |item_ref| {
11034 const item = try sema.resolveInst(item_ref);11055 const item = try sema.resolveInst(item_ref);
11035 // Validation above ensured these will succeed.11056 // Validation above ensured these will succeed.
11036 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable;11057 const item_val = sema.resolveConstLazyValue(&child_block, .unneeded, item, "") catch unreachable;
11037 if (operand_val.eql(item_val, operand_ty, mod)) {11058 if (resolved_operand_val.eql(item_val, operand_ty, mod)) {
11038 if (is_inline) child_block.inline_case_capture = operand;11059 if (is_inline) child_block.inline_case_capture = operand;
1103911060
11040 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);11061 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);
...@@ -11052,8 +11073,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11052,8 +11073,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11052 // Validation above ensured these will succeed.11073 // Validation above ensured these will succeed.
11053 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, "") catch unreachable;11074 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, "") catch unreachable;
11054 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, "") catch unreachable;11075 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, "") catch unreachable;
11055 if ((try sema.compareAll(operand_val, .gte, first_tv.val, operand_ty)) and11076 if ((try sema.compareAll(resolved_operand_val, .gte, first_tv.val, operand_ty)) and
11056 (try sema.compareAll(operand_val, .lte, last_tv.val, operand_ty)))11077 (try sema.compareAll(resolved_operand_val, .lte, last_tv.val, operand_ty)))
11057 {11078 {
11058 if (is_inline) child_block.inline_case_capture = operand;11079 if (is_inline) child_block.inline_case_capture = operand;
11059 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);11080 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);
...@@ -11135,7 +11156,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11135,7 +11156,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11135 // `item` is already guaranteed to be constant known.11156 // `item` is already guaranteed to be constant known.
1113611157
11137 const analyze_body = if (union_originally) blk: {11158 const analyze_body = if (union_originally) blk: {
11138 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;11159 const item_val = sema.resolveConstLazyValue(block, .unneeded, item, "") catch unreachable;
11139 const field_ty = maybe_union_ty.unionFieldType(item_val, mod);11160 const field_ty = maybe_union_ty.unionFieldType(item_val, mod);
11140 break :blk field_ty.zigTypeTag(mod) != .NoReturn;11161 break :blk field_ty.zigTypeTag(mod) != .NoReturn;
11141 } else true;11162 } else true;
...@@ -11683,8 +11704,7 @@ fn resolveSwitchItemVal(...@@ -11683,8 +11704,7 @@ fn resolveSwitchItemVal(
11683 // Constructing a LazySrcLoc is costly because we only have the switch AST node.11704 // Constructing a LazySrcLoc is costly because we only have the switch AST node.
11684 // Only if we know for sure we need to report a compile error do we resolve the11705 // Only if we know for sure we need to report a compile error do we resolve the
11685 // full source locations.11706 // full source locations.
11686 if (sema.resolveConstValue(block, .unneeded, item, "")) |val| {11707 if (sema.resolveConstLazyValue(block, .unneeded, item, "")) |val| {
11687 try sema.resolveLazyValue(val);
11688 return val.toIntern();11708 return val.toIntern();
11689 } else |err| switch (err) {11709 } else |err| switch (err) {
11690 error.NeededSourceLocation => {11710 error.NeededSourceLocation => {
...@@ -20634,9 +20654,8 @@ fn zirBitCount(...@@ -20634,9 +20654,8 @@ fn zirBitCount(
20634 }20654 }
20635 },20655 },
20636 .Int => {20656 .Int => {
20637 if (try sema.resolveMaybeUndefVal(operand)) |val| {20657 if (try sema.resolveMaybeUndefLazyVal(operand)) |val| {
20638 if (val.isUndef(mod)) return sema.addConstUndef(result_scalar_ty);20658 if (val.isUndef(mod)) return sema.addConstUndef(result_scalar_ty);
20639 try sema.resolveLazyValue(val);
20640 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, mod));20659 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, mod));
20641 } else {20660 } else {
20642 try sema.requireRuntimeBlock(block, src, operand_src);20661 try sema.requireRuntimeBlock(block, src, operand_src);
...@@ -22311,18 +22330,18 @@ fn analyzeMinMax(...@@ -22311,18 +22330,18 @@ fn analyzeMinMax(
22311 continue;22330 continue;
22312 }22331 }
2231322332
22314 try sema.resolveLazyValue(cur_val);22333 const resolved_cur_val = try sema.resolveLazyValue(cur_val);
22315 try sema.resolveLazyValue(operand_val);22334 const resolved_operand_val = try sema.resolveLazyValue(operand_val);
2231622335
22317 const vec_len = simd_op.len orelse {22336 const vec_len = simd_op.len orelse {
22318 const result_val = opFunc(cur_val, operand_val, mod);22337 const result_val = opFunc(resolved_cur_val, resolved_operand_val, mod);
22319 cur_minmax = try sema.addConstant(simd_op.result_ty, result_val);22338 cur_minmax = try sema.addConstant(simd_op.result_ty, result_val);
22320 continue;22339 continue;
22321 };22340 };
22322 const elems = try sema.arena.alloc(InternPool.Index, vec_len);22341 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
22323 for (elems, 0..) |*elem, i| {22342 for (elems, 0..) |*elem, i| {
22324 const lhs_elem_val = try cur_val.elemValue(mod, i);22343 const lhs_elem_val = try resolved_cur_val.elemValue(mod, i);
22325 const rhs_elem_val = try operand_val.elemValue(mod, i);22344 const rhs_elem_val = try resolved_operand_val.elemValue(mod, i);
22326 elem.* = try opFunc(lhs_elem_val, rhs_elem_val, mod).intern(simd_op.scalar_ty, mod);22345 elem.* = try opFunc(lhs_elem_val, rhs_elem_val, mod).intern(simd_op.scalar_ty, mod);
22327 }22346 }
22328 cur_minmax = try sema.addConstant(simd_op.result_ty, (try mod.intern(.{ .aggregate = .{22347 cur_minmax = try sema.addConstant(simd_op.result_ty, (try mod.intern(.{ .aggregate = .{
...@@ -30360,13 +30379,11 @@ fn cmpNumeric(...@@ -30360,13 +30379,11 @@ fn cmpNumeric(
30360 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {30379 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
30361 // Compare ints: const vs. undefined (or vice versa)30380 // Compare ints: const vs. undefined (or vice versa)
30362 if (!lhs_val.isUndef(mod) and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod) and rhs_val.isUndef(mod)) {30381 if (!lhs_val.isUndef(mod) and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod) and rhs_val.isUndef(mod)) {
30363 try sema.resolveLazyValue(lhs_val);30382 if (try sema.compareIntsOnlyPossibleResult(try sema.resolveLazyValue(lhs_val), op, rhs_ty)) |res| {
30364 if (try sema.compareIntsOnlyPossibleResult(lhs_val, op, rhs_ty)) |res| {
30365 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;30383 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
30366 }30384 }
30367 } else if (!rhs_val.isUndef(mod) and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod) and lhs_val.isUndef(mod)) {30385 } else if (!rhs_val.isUndef(mod) and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod) and lhs_val.isUndef(mod)) {
30368 try sema.resolveLazyValue(rhs_val);30386 if (try sema.compareIntsOnlyPossibleResult(try sema.resolveLazyValue(rhs_val), op.reverse(), lhs_ty)) |res| {
30369 if (try sema.compareIntsOnlyPossibleResult(rhs_val, op.reverse(), lhs_ty)) |res| {
30370 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;30387 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
30371 }30388 }
30372 }30389 }
...@@ -30389,19 +30406,17 @@ fn cmpNumeric(...@@ -30389,19 +30406,17 @@ fn cmpNumeric(
30389 } else {30406 } else {
30390 if (!lhs_val.isUndef(mod) and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod)) {30407 if (!lhs_val.isUndef(mod) and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod)) {
30391 // Compare ints: const vs. var30408 // Compare ints: const vs. var
30392 try sema.resolveLazyValue(lhs_val);30409 if (try sema.compareIntsOnlyPossibleResult(try sema.resolveLazyValue(lhs_val), op, rhs_ty)) |res| {
30393 if (try sema.compareIntsOnlyPossibleResult(lhs_val, op, rhs_ty)) |res| {
30394 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;30410 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
30395 }30411 }
30396 }30412 }
30397 break :src rhs_src;30413 break :src rhs_src;
30398 }30414 }
30399 } else {30415 } else {
30400 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {30416 if (try sema.resolveMaybeUndefLazyVal(rhs)) |rhs_val| {
30401 if (!rhs_val.isUndef(mod) and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod)) {30417 if (!rhs_val.isUndef(mod) and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod)) {
30402 // Compare ints: var vs. const30418 // Compare ints: var vs. const
30403 try sema.resolveLazyValue(rhs_val);30419 if (try sema.compareIntsOnlyPossibleResult(try sema.resolveLazyValue(rhs_val), op.reverse(), lhs_ty)) |res| {
30404 if (try sema.compareIntsOnlyPossibleResult(rhs_val, op.reverse(), lhs_ty)) |res| {
30405 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;30420 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
30406 }30421 }
30407 }30422 }
...@@ -30465,8 +30480,7 @@ fn cmpNumeric(...@@ -30465,8 +30480,7 @@ fn cmpNumeric(
30465 var dest_float_type: ?Type = null;30480 var dest_float_type: ?Type = null;
3046630481
30467 var lhs_bits: usize = undefined;30482 var lhs_bits: usize = undefined;
30468 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {30483 if (try sema.resolveMaybeUndefLazyVal(lhs)) |lhs_val| {
30469 try sema.resolveLazyValue(lhs_val);
30470 if (lhs_val.isUndef(mod))30484 if (lhs_val.isUndef(mod))
30471 return sema.addConstUndef(Type.bool);30485 return sema.addConstUndef(Type.bool);
30472 if (lhs_val.isNan(mod)) switch (op) {30486 if (lhs_val.isNan(mod)) switch (op) {
...@@ -30524,8 +30538,7 @@ fn cmpNumeric(...@@ -30524,8 +30538,7 @@ fn cmpNumeric(
30524 }30538 }
3052530539
30526 var rhs_bits: usize = undefined;30540 var rhs_bits: usize = undefined;
30527 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {30541 if (try sema.resolveMaybeUndefLazyVal(rhs)) |rhs_val| {
30528 try sema.resolveLazyValue(rhs_val);
30529 if (rhs_val.isUndef(mod))30542 if (rhs_val.isUndef(mod))
30530 return sema.addConstUndef(Type.bool);30543 return sema.addConstUndef(Type.bool);
30531 if (rhs_val.isNan(mod)) switch (op) {30544 if (rhs_val.isNan(mod)) switch (op) {
...@@ -31467,32 +31480,133 @@ pub fn resolveFnTypes(sema: *Sema, fn_info: InternPool.Key.FuncType) CompileErro...@@ -31467,32 +31480,133 @@ pub fn resolveFnTypes(sema: *Sema, fn_info: InternPool.Key.FuncType) CompileErro
3146731480
31468/// Make it so that calling hash() and eql() on `val` will not assert due31481/// Make it so that calling hash() and eql() on `val` will not assert due
31469/// to a type not having its layout resolved.31482/// to a type not having its layout resolved.
31470fn resolveLazyValue(sema: *Sema, val: Value) CompileError!void {31483fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
31471 switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {31484 const mod = sema.mod;
31485 switch (mod.intern_pool.indexToKey(val.toIntern())) {
31472 .int => |int| switch (int.storage) {31486 .int => |int| switch (int.storage) {
31473 .u64, .i64, .big_int => {},31487 .u64, .i64, .big_int => return val,
31474 .lazy_align, .lazy_size => |lazy_ty| try sema.resolveTypeLayout(lazy_ty.toType()),31488 .lazy_align, .lazy_size => return (try mod.intern(.{ .int = .{
31489 .ty = int.ty,
31490 .storage = .{ .u64 = (try val.getUnsignedIntAdvanced(mod, sema)).? },
31491 } })).toValue(),
31475 },31492 },
31476 .ptr => |ptr| {31493 .ptr => |ptr| {
31494 const resolved_len = switch (ptr.len) {
31495 .none => .none,
31496 else => (try sema.resolveLazyValue(ptr.len.toValue())).toIntern(),
31497 };
31477 switch (ptr.addr) {31498 switch (ptr.addr) {
31478 .decl, .mut_decl => {},31499 .decl, .mut_decl => return if (resolved_len == ptr.len)
31479 .int => |int| try sema.resolveLazyValue(int.toValue()),31500 val
31480 .eu_payload, .opt_payload => |base| try sema.resolveLazyValue(base.toValue()),31501 else
31481 .comptime_field => |comptime_field| try sema.resolveLazyValue(comptime_field.toValue()),31502 (try mod.intern(.{ .ptr = .{
31482 .elem, .field => |base_index| try sema.resolveLazyValue(base_index.base.toValue()),31503 .ty = ptr.ty,
31504 .addr = switch (ptr.addr) {
31505 .decl => |decl| .{ .decl = decl },
31506 .mut_decl => |mut_decl| .{ .mut_decl = mut_decl },
31507 else => unreachable,
31508 },
31509 .len = resolved_len,
31510 } })).toValue(),
31511 .comptime_field => |field_val| {
31512 const resolved_field_val =
31513 (try sema.resolveLazyValue(field_val.toValue())).toIntern();
31514 return if (resolved_field_val == field_val and resolved_len == ptr.len)
31515 val
31516 else
31517 (try mod.intern(.{ .ptr = .{
31518 .ty = ptr.ty,
31519 .addr = .{ .comptime_field = resolved_field_val },
31520 .len = resolved_len,
31521 } })).toValue();
31522 },
31523 .int => |int| {
31524 const resolved_int = (try sema.resolveLazyValue(int.toValue())).toIntern();
31525 return if (resolved_int == int and resolved_len == ptr.len)
31526 val
31527 else
31528 (try mod.intern(.{ .ptr = .{
31529 .ty = ptr.ty,
31530 .addr = .{ .int = resolved_int },
31531 .len = resolved_len,
31532 } })).toValue();
31533 },
31534 .eu_payload, .opt_payload => |base| {
31535 const resolved_base = (try sema.resolveLazyValue(base.toValue())).toIntern();
31536 return if (resolved_base == base and resolved_len == ptr.len)
31537 val
31538 else
31539 (try mod.intern(.{ .ptr = .{
31540 .ty = ptr.ty,
31541 .addr = switch (ptr.addr) {
31542 .eu_payload => .{ .eu_payload = resolved_base },
31543 .opt_payload => .{ .opt_payload = resolved_base },
31544 else => unreachable,
31545 },
31546 .len = ptr.len,
31547 } })).toValue();
31548 },
31549 .elem, .field => |base_index| {
31550 const resolved_base = (try sema.resolveLazyValue(base_index.base.toValue())).toIntern();
31551 return if (resolved_base == base_index.base and resolved_len == ptr.len)
31552 val
31553 else
31554 (try mod.intern(.{ .ptr = .{
31555 .ty = ptr.ty,
31556 .addr = switch (ptr.addr) {
31557 .elem => .{ .elem = .{
31558 .base = resolved_base,
31559 .index = base_index.index,
31560 } },
31561 .field => .{ .field = .{
31562 .base = resolved_base,
31563 .index = base_index.index,
31564 } },
31565 else => unreachable,
31566 },
31567 .len = ptr.len,
31568 } })).toValue();
31569 },
31483 }31570 }
31484 if (ptr.len != .none) try sema.resolveLazyValue(ptr.len.toValue());
31485 },31571 },
31486 .aggregate => |aggregate| switch (aggregate.storage) {31572 .aggregate => |aggregate| switch (aggregate.storage) {
31487 .bytes => {},31573 .bytes => return val,
31488 .elems => |elems| for (elems) |elem| try sema.resolveLazyValue(elem.toValue()),31574 .elems => |elems| {
31489 .repeated_elem => |elem| try sema.resolveLazyValue(elem.toValue()),31575 var resolved_elems: []InternPool.Index = &.{};
31576 for (elems, 0..) |elem, i| {
31577 const resolved_elem = (try sema.resolveLazyValue(elem.toValue())).toIntern();
31578 if (resolved_elems.len == 0 and resolved_elem != elem) {
31579 resolved_elems = try sema.arena.alloc(InternPool.Index, elems.len);
31580 @memcpy(resolved_elems[0..i], elems[0..i]);
31581 }
31582 if (resolved_elems.len > 0) resolved_elems[i] = resolved_elem;
31583 }
31584 return if (resolved_elems.len == 0) val else (try mod.intern(.{ .aggregate = .{
31585 .ty = aggregate.ty,
31586 .storage = .{ .elems = resolved_elems },
31587 } })).toValue();
31588 },
31589 .repeated_elem => |elem| {
31590 const resolved_elem = (try sema.resolveLazyValue(elem.toValue())).toIntern();
31591 return if (resolved_elem == elem) val else (try mod.intern(.{ .aggregate = .{
31592 .ty = aggregate.ty,
31593 .storage = .{ .repeated_elem = resolved_elem },
31594 } })).toValue();
31595 },
31490 },31596 },
31491 .un => |un| {31597 .un => |un| {
31492 try sema.resolveLazyValue(un.tag.toValue());31598 const resolved_tag = (try sema.resolveLazyValue(un.tag.toValue())).toIntern();
31493 try sema.resolveLazyValue(un.val.toValue());31599 const resolved_val = (try sema.resolveLazyValue(un.val.toValue())).toIntern();
31600 return if (resolved_tag == un.tag and resolved_val == un.val)
31601 val
31602 else
31603 (try mod.intern(.{ .un = .{
31604 .ty = un.ty,
31605 .tag = resolved_tag,
31606 .val = resolved_val,
31607 } })).toValue();
31494 },31608 },
31495 else => {},31609 else => return val,
31496 }31610 }
31497}31611}
3149831612