diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 7 | ||||
| -rw-r--r-- | src/value.zig | 28 |
2 files changed, 32 insertions, 3 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index fb45c9e9d3..a33861c74c 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -4618,7 +4618,7 @@ fn analyzeCall( }, else => {}, } - should_memoize = should_memoize and !arg_val.isComptimeMutablePtr(); + should_memoize = should_memoize and !arg_val.canMutateComptimeVarState(); memoized_call_key.args[arg_i] = .{ .ty = param_ty, .val = arg_val, @@ -4644,7 +4644,7 @@ fn analyzeCall( }, else => {}, } - should_memoize = should_memoize and !arg_val.isComptimeMutablePtr(); + should_memoize = should_memoize and !arg_val.canMutateComptimeVarState(); memoized_call_key.args[arg_i] = .{ .ty = sema.typeOf(uncasted_arg), .val = arg_val, @@ -13603,7 +13603,8 @@ fn analyzeShuffle( // in 1 call because these calls to analyzeShuffle guarantee a_len == b_len. if (a_len != b_len) { const min_len = std.math.min(a_len, b_len); - const max_len = std.math.max(a_len, b_len); + const max_src = if (a_len > b_len) a_src else b_src; + const max_len = try sema.usizeCast(block, max_src, std.math.max(a_len, b_len)); const expand_mask_values = try sema.arena.alloc(Value, max_len); i = 0; diff --git a/src/value.zig b/src/value.zig index 973e477099..9117ef78df 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1157,6 +1157,7 @@ pub const Value = extern union { ) Allocator.Error!Value { switch (ty.zigTypeTag()) { .Int => { + if (buffer.len == 0) return Value.zero; const int_info = ty.intInfo(target); const endian = target.cpu.arch.endian(); const Limb = std.math.big.Limb; @@ -2185,6 +2186,33 @@ pub const Value = extern union { }; } + pub fn canMutateComptimeVarState(val: Value) bool { + if (val.isComptimeMutablePtr()) return true; + switch (val.tag()) { + .repeated => return val.castTag(.repeated).?.data.canMutateComptimeVarState(), + .array => { + const elems = val.cast(Payload.Array).?.data; + for (elems) |elem| { + if (elem.canMutateComptimeVarState()) return true; + } + return false; + }, + .eu_payload => return val.castTag(.eu_payload).?.data.canMutateComptimeVarState(), + .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.canMutateComptimeVarState(), + .opt_payload => return val.castTag(.opt_payload).?.data.canMutateComptimeVarState(), + .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.canMutateComptimeVarState(), + .@"struct" => { + const fields = val.cast(Payload.Struct).?.data; + for (fields) |field| { + if (field.canMutateComptimeVarState()) return true; + } + return false; + }, + .@"union" => return val.cast(Payload.Union).?.data.val.canMutateComptimeVarState(), + else => return false, + } + } + /// Gets the decl referenced by this pointer. If the pointer does not point /// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr), /// this function returns null. |
