| ... | @@ -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 | } |
| 1917 | | 1917 | |
| | 1918 | /// Will not return Value Tags: `variable`, `undef`. Instead they will emit compile errors. |
| | 1919 | /// Lazy values are recursively resolved. |
| | 1920 | fn 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. |
| 1920 | fn resolveDefinedValue( | 1932 | fn resolveDefinedValue( |
| ... | @@ -1952,10 +1964,22 @@ fn resolveMaybeUndefVal( | ... | @@ -1952,10 +1964,22 @@ fn resolveMaybeUndefVal( |
| 1952 | } | 1964 | } |
| 1953 | } | 1965 | } |
| 1954 | | 1966 | |
| | 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. |
| | 1971 | fn 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. |
| 1959 | fn resolveMaybeUndefValIntable( | 1983 | fn 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 | } |
| 1982 | | 2005 | |
| 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( |
| 5257 | | 5280 | |
| 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 | } |
| 7370 | | 7390 | |
| 7371 | fn analyzeGenericCallArgVal(sema: *Sema, block: *Block, arg_src: LazySrcLoc, uncasted_arg: Air.Inst.Ref) !Value { | 7391 | fn 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 | } |
| 7376 | | 7394 | |
| 7377 | fn instantiateGenericCall( | 7395 | fn 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 | } |
| 7909 | | 7928 | |
| ... | @@ -10104,8 +10123,9 @@ fn zirSwitchCapture( | ... | @@ -10104,8 +10123,9 @@ fn zirSwitchCapture( |
| 10104 | | 10123 | |
| 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 succeed | 10271 | // 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 succeed | 10281 | // 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; |
| 10263 | | 10283 | |
| 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); |
| 10994 | | 11014 | |
| 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 |
| 11007 | | 11028 | |
| 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; |
| 11013 | | 11034 | |
| 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; |
| 11039 | | 11060 | |
| 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)) and | 11076 | 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. |
| 11136 | | 11157 | |
| 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 the | 11705 | // 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 | } |
| 22313 | | 22332 | |
| 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); |
| 22316 | | 22335 | |
| 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. var | 30408 | // 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. const | 30418 | // 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; |
| 30466 | | 30481 | |
| 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 | } |
| 30525 | | 30539 | |
| 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 |
| 31467 | | 31480 | |
| 31468 | /// Make it so that calling hash() and eql() on `val` will not assert due | 31481 | /// 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. |
| 31470 | fn resolveLazyValue(sema: *Sema, val: Value) CompileError!void { | 31483 | fn 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 | } |
| 31498 | | 31612 | |