mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Sema: remove block and src parameters from getBuiltin
These parameters are only ever needed when `std.builtin` is out of sync with the compiler in which case panicking is the only valid operation anyways. Removing them causes a domino effect of functions no longer needing a `src` and/or a `block` parameter resulting in handling compilation errors where they are actually meaningful becoming simpler.
This commit is contained in:
parent
b2ffe113d3
commit
0184c8d86f
@ -224,12 +224,6 @@ const MonomorphedFuncsContext = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const WipAnalysis = struct {
|
||||
sema: *Sema,
|
||||
block: *Sema.Block,
|
||||
src: Module.LazySrcLoc,
|
||||
};
|
||||
|
||||
pub const MemoizedCallSet = std.HashMapUnmanaged(
|
||||
MemoizedCall.Key,
|
||||
MemoizedCall.Result,
|
||||
@ -4642,7 +4636,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
|
||||
// Note this resolves the type of the Decl, not the value; if this Decl
|
||||
// is a struct, for example, this resolves `type` (which needs no resolution),
|
||||
// not the struct itself.
|
||||
try sema.resolveTypeLayout(&block_scope, ty_src, decl_tv.ty);
|
||||
try sema.resolveTypeLayout(decl_tv.ty);
|
||||
|
||||
const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);
|
||||
|
||||
@ -4810,14 +4804,14 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
|
||||
decl.generation = mod.generation;
|
||||
|
||||
const has_runtime_bits = is_extern or
|
||||
(queue_linker_work and try sema.typeHasRuntimeBits(&block_scope, ty_src, decl.ty));
|
||||
(queue_linker_work and try sema.typeHasRuntimeBits(decl.ty));
|
||||
|
||||
if (has_runtime_bits) {
|
||||
log.debug("queue linker work for {*} ({s})", .{ decl, decl.name });
|
||||
|
||||
// Needed for codegen_decl which will call updateDecl and then the
|
||||
// codegen backend wants full access to the Decl Type.
|
||||
try sema.resolveTypeFully(&block_scope, ty_src, decl.ty);
|
||||
try sema.resolveTypeFully(decl.ty);
|
||||
|
||||
try mod.comp.bin_file.allocateDeclIndexes(decl_index);
|
||||
try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
|
||||
@ -5586,21 +5580,10 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
|
||||
var runtime_param_index: usize = 0;
|
||||
var total_param_index: usize = 0;
|
||||
for (fn_info.param_body) |inst| {
|
||||
const param: struct { name: u32, src: LazySrcLoc } = switch (zir_tags[inst]) {
|
||||
.param, .param_comptime => blk: {
|
||||
const pl_tok = sema.code.instructions.items(.data)[inst].pl_tok;
|
||||
const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index).data;
|
||||
break :blk .{ .name = extra.name, .src = pl_tok.src() };
|
||||
},
|
||||
|
||||
.param_anytype, .param_anytype_comptime => blk: {
|
||||
const str_tok = sema.code.instructions.items(.data)[inst].str_tok;
|
||||
break :blk .{ .name = str_tok.start, .src = str_tok.src() };
|
||||
},
|
||||
|
||||
switch (zir_tags[inst]) {
|
||||
.param, .param_comptime, .param_anytype, .param_anytype_comptime => {},
|
||||
else => continue,
|
||||
};
|
||||
|
||||
}
|
||||
const param_ty = if (func.comptime_args) |comptime_args| t: {
|
||||
const arg_tv = comptime_args[total_param_index];
|
||||
|
||||
@ -5617,7 +5600,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
|
||||
continue;
|
||||
} else fn_ty_info.param_types[runtime_param_index];
|
||||
|
||||
const opt_opv = sema.typeHasOnePossibleValue(&inner_block, param.src, param_ty) catch |err| switch (err) {
|
||||
const opt_opv = sema.typeHasOnePossibleValue(param_ty) catch |err| switch (err) {
|
||||
error.NeededSourceLocation => unreachable,
|
||||
error.GenericPoison => unreachable,
|
||||
error.ComptimeReturn => unreachable,
|
||||
@ -5707,8 +5690,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
|
||||
// Crucially, this happens *after* we set the function state to success above,
|
||||
// so that dependencies on the function body will now be satisfied rather than
|
||||
// result in circular dependency errors.
|
||||
const src = LazySrcLoc.nodeOffset(0);
|
||||
sema.resolveFnTypes(&inner_block, src, fn_ty_info) catch |err| switch (err) {
|
||||
sema.resolveFnTypes(fn_ty_info) catch |err| switch (err) {
|
||||
error.NeededSourceLocation => unreachable,
|
||||
error.GenericPoison => unreachable,
|
||||
error.ComptimeReturn => unreachable,
|
||||
@ -5726,7 +5708,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
|
||||
// the backends.
|
||||
for (sema.types_to_resolve.items) |inst_ref| {
|
||||
const ty = sema.getTmpAir().getRefType(inst_ref);
|
||||
sema.resolveTypeFully(&inner_block, src, ty) catch |err| switch (err) {
|
||||
sema.resolveTypeFully(ty) catch |err| switch (err) {
|
||||
error.NeededSourceLocation => unreachable,
|
||||
error.GenericPoison => unreachable,
|
||||
error.ComptimeReturn => unreachable,
|
||||
|
||||
1520
src/Sema.zig
1520
src/Sema.zig
File diff suppressed because it is too large
Load Diff
154
src/type.zig
154
src/type.zig
@ -7,6 +7,7 @@ const Module = @import("Module.zig");
|
||||
const log = std.log.scoped(.Type);
|
||||
const target_util = @import("target.zig");
|
||||
const TypedValue = @import("TypedValue.zig");
|
||||
const Sema = @import("Sema.zig");
|
||||
|
||||
const file_struct = @This();
|
||||
|
||||
@ -2325,7 +2326,7 @@ pub const Type = extern union {
|
||||
pub fn hasRuntimeBitsAdvanced(
|
||||
ty: Type,
|
||||
ignore_comptime_only: bool,
|
||||
sema_kit: ?Module.WipAnalysis,
|
||||
opt_sema: ?*Sema,
|
||||
) Module.CompileError!bool {
|
||||
switch (ty.tag()) {
|
||||
.u1,
|
||||
@ -2405,8 +2406,8 @@ pub const Type = extern union {
|
||||
return true;
|
||||
} else if (ty.childType().zigTypeTag() == .Fn) {
|
||||
return !ty.childType().fnInfo().is_generic;
|
||||
} else if (sema_kit) |sk| {
|
||||
return !(try sk.sema.typeRequiresComptime(ty));
|
||||
} else if (opt_sema) |sema| {
|
||||
return !(try sema.typeRequiresComptime(ty));
|
||||
} else {
|
||||
return !comptimeOnly(ty);
|
||||
}
|
||||
@ -2444,8 +2445,8 @@ pub const Type = extern union {
|
||||
}
|
||||
if (ignore_comptime_only) {
|
||||
return true;
|
||||
} else if (sema_kit) |sk| {
|
||||
return !(try sk.sema.typeRequiresComptime(child_ty));
|
||||
} else if (opt_sema) |sema| {
|
||||
return !(try sema.typeRequiresComptime(child_ty));
|
||||
} else {
|
||||
return !comptimeOnly(child_ty);
|
||||
}
|
||||
@ -2458,13 +2459,13 @@ pub const Type = extern union {
|
||||
// and then later if our guess was incorrect, we emit a compile error.
|
||||
return true;
|
||||
}
|
||||
if (sema_kit) |sk| {
|
||||
_ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
|
||||
if (opt_sema) |sema| {
|
||||
_ = try sema.resolveTypeFields(ty);
|
||||
}
|
||||
assert(struct_obj.haveFieldTypes());
|
||||
for (struct_obj.fields.values()) |field| {
|
||||
if (field.is_comptime) continue;
|
||||
if (try field.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit))
|
||||
if (try field.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, opt_sema))
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -2473,7 +2474,7 @@ pub const Type = extern union {
|
||||
|
||||
.enum_full => {
|
||||
const enum_full = ty.castTag(.enum_full).?.data;
|
||||
return enum_full.tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit);
|
||||
return enum_full.tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, opt_sema);
|
||||
},
|
||||
.enum_simple => {
|
||||
const enum_simple = ty.castTag(.enum_simple).?.data;
|
||||
@ -2482,17 +2483,17 @@ pub const Type = extern union {
|
||||
.enum_numbered, .enum_nonexhaustive => {
|
||||
var buffer: Payload.Bits = undefined;
|
||||
const int_tag_ty = ty.intTagType(&buffer);
|
||||
return int_tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit);
|
||||
return int_tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, opt_sema);
|
||||
},
|
||||
|
||||
.@"union" => {
|
||||
const union_obj = ty.castTag(.@"union").?.data;
|
||||
if (sema_kit) |sk| {
|
||||
_ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
|
||||
if (opt_sema) |sema| {
|
||||
_ = try sema.resolveTypeFields(ty);
|
||||
}
|
||||
assert(union_obj.haveFieldTypes());
|
||||
for (union_obj.fields.values()) |value| {
|
||||
if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit))
|
||||
if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, opt_sema))
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -2500,16 +2501,16 @@ pub const Type = extern union {
|
||||
},
|
||||
.union_safety_tagged, .union_tagged => {
|
||||
const union_obj = ty.cast(Payload.Union).?.data;
|
||||
if (try union_obj.tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit)) {
|
||||
if (try union_obj.tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, opt_sema)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sema_kit) |sk| {
|
||||
_ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
|
||||
if (opt_sema) |sema| {
|
||||
_ = try sema.resolveTypeFields(ty);
|
||||
}
|
||||
assert(union_obj.haveFieldTypes());
|
||||
for (union_obj.fields.values()) |value| {
|
||||
if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit))
|
||||
if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, opt_sema))
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -2517,9 +2518,9 @@ pub const Type = extern union {
|
||||
},
|
||||
|
||||
.array, .vector => return ty.arrayLen() != 0 and
|
||||
try ty.elemType().hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit),
|
||||
try ty.elemType().hasRuntimeBitsAdvanced(ignore_comptime_only, opt_sema),
|
||||
.array_u8 => return ty.arrayLen() != 0,
|
||||
.array_sentinel => return ty.childType().hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit),
|
||||
.array_sentinel => return ty.childType().hasRuntimeBitsAdvanced(ignore_comptime_only, opt_sema),
|
||||
|
||||
.int_signed, .int_unsigned => return ty.cast(Payload.Bits).?.data != 0,
|
||||
|
||||
@ -2528,7 +2529,7 @@ pub const Type = extern union {
|
||||
for (tuple.types) |field_ty, i| {
|
||||
const val = tuple.values[i];
|
||||
if (val.tag() != .unreachable_value) continue; // comptime field
|
||||
if (try field_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit)) return true;
|
||||
if (try field_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, opt_sema)) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
@ -2721,7 +2722,7 @@ pub const Type = extern union {
|
||||
return ptrAlignmentAdvanced(ty, target, null) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn ptrAlignmentAdvanced(ty: Type, target: Target, sema_kit: ?Module.WipAnalysis) !u32 {
|
||||
pub fn ptrAlignmentAdvanced(ty: Type, target: Target, opt_sema: ?*Sema) !u32 {
|
||||
switch (ty.tag()) {
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
@ -2735,8 +2736,8 @@ pub const Type = extern union {
|
||||
.optional_single_mut_pointer,
|
||||
=> {
|
||||
const child_type = ty.cast(Payload.ElemType).?.data;
|
||||
if (sema_kit) |sk| {
|
||||
const res = try child_type.abiAlignmentAdvanced(target, .{ .sema_kit = sk });
|
||||
if (opt_sema) |sema| {
|
||||
const res = try child_type.abiAlignmentAdvanced(target, .{ .sema = sema });
|
||||
return res.scalar;
|
||||
}
|
||||
return (child_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;
|
||||
@ -2753,14 +2754,14 @@ pub const Type = extern union {
|
||||
const ptr_info = ty.castTag(.pointer).?.data;
|
||||
if (ptr_info.@"align" != 0) {
|
||||
return ptr_info.@"align";
|
||||
} else if (sema_kit) |sk| {
|
||||
const res = try ptr_info.pointee_type.abiAlignmentAdvanced(target, .{ .sema_kit = sk });
|
||||
} else if (opt_sema) |sema| {
|
||||
const res = try ptr_info.pointee_type.abiAlignmentAdvanced(target, .{ .sema = sema });
|
||||
return res.scalar;
|
||||
} else {
|
||||
return (ptr_info.pointee_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;
|
||||
}
|
||||
},
|
||||
.optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(target, sema_kit),
|
||||
.optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(target, opt_sema),
|
||||
|
||||
else => unreachable,
|
||||
}
|
||||
@ -2819,22 +2820,22 @@ pub const Type = extern union {
|
||||
const AbiAlignmentAdvancedStrat = union(enum) {
|
||||
eager,
|
||||
lazy: Allocator,
|
||||
sema_kit: Module.WipAnalysis,
|
||||
sema: *Sema,
|
||||
};
|
||||
|
||||
/// If you pass `eager` you will get back `scalar` and assert the type is resolved.
|
||||
/// In this case there will be no error, guaranteed.
|
||||
/// If you pass `lazy` you may get back `scalar` or `val`.
|
||||
/// If `val` is returned, a reference to `ty` has been captured.
|
||||
/// If you pass `sema_kit` you will get back `scalar` and resolve the type if
|
||||
/// If you pass `sema` you will get back `scalar` and resolve the type if
|
||||
/// necessary, possibly returning a CompileError.
|
||||
pub fn abiAlignmentAdvanced(
|
||||
ty: Type,
|
||||
target: Target,
|
||||
strat: AbiAlignmentAdvancedStrat,
|
||||
) Module.CompileError!AbiAlignmentAdvanced {
|
||||
const sema_kit = switch (strat) {
|
||||
.sema_kit => |sk| sk,
|
||||
const opt_sema = switch (strat) {
|
||||
.sema => |sema| sema,
|
||||
else => null,
|
||||
};
|
||||
switch (ty.tag()) {
|
||||
@ -2939,7 +2940,7 @@ pub const Type = extern union {
|
||||
|
||||
.vector => {
|
||||
const len = ty.arrayLen();
|
||||
const bits = try bitSizeAdvanced(ty.elemType(), target, sema_kit);
|
||||
const bits = try bitSizeAdvanced(ty.elemType(), target, opt_sema);
|
||||
const bytes = ((bits * len) + 7) / 8;
|
||||
const alignment = std.math.ceilPowerOfTwoAssert(u64, bytes);
|
||||
return AbiAlignmentAdvanced{ .scalar = @intCast(u32, alignment) };
|
||||
@ -2969,8 +2970,8 @@ pub const Type = extern union {
|
||||
}
|
||||
|
||||
switch (strat) {
|
||||
.eager, .sema_kit => {
|
||||
if (!(try child_type.hasRuntimeBitsAdvanced(false, sema_kit))) {
|
||||
.eager, .sema => {
|
||||
if (!(try child_type.hasRuntimeBitsAdvanced(false, opt_sema))) {
|
||||
return AbiAlignmentAdvanced{ .scalar = 1 };
|
||||
}
|
||||
return child_type.abiAlignmentAdvanced(target, strat);
|
||||
@ -2988,8 +2989,8 @@ pub const Type = extern union {
|
||||
const data = ty.castTag(.error_union).?.data;
|
||||
const code_align = abiAlignment(Type.anyerror, target);
|
||||
switch (strat) {
|
||||
.eager, .sema_kit => {
|
||||
if (!(try data.payload.hasRuntimeBitsAdvanced(false, sema_kit))) {
|
||||
.eager, .sema => {
|
||||
if (!(try data.payload.hasRuntimeBitsAdvanced(false, opt_sema))) {
|
||||
return AbiAlignmentAdvanced{ .scalar = code_align };
|
||||
}
|
||||
return AbiAlignmentAdvanced{ .scalar = @max(
|
||||
@ -3013,22 +3014,22 @@ pub const Type = extern union {
|
||||
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
if (sema_kit) |sk| {
|
||||
if (opt_sema) |sema| {
|
||||
if (struct_obj.status == .field_types_wip) {
|
||||
// We'll guess "pointer-aligned" and if we guess wrong, emit
|
||||
// a compile error later.
|
||||
return AbiAlignmentAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) };
|
||||
}
|
||||
_ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
|
||||
_ = try sema.resolveTypeFields(ty);
|
||||
}
|
||||
if (!struct_obj.haveFieldTypes()) switch (strat) {
|
||||
.eager => unreachable, // struct layout not resolved
|
||||
.sema_kit => unreachable, // handled above
|
||||
.sema => unreachable, // handled above
|
||||
.lazy => |arena| return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) },
|
||||
};
|
||||
if (struct_obj.layout == .Packed) {
|
||||
switch (strat) {
|
||||
.sema_kit => |sk| try sk.sema.resolveTypeLayout(sk.block, sk.src, ty),
|
||||
.sema => |sema| try sema.resolveTypeLayout(ty),
|
||||
.lazy => |arena| {
|
||||
if (!struct_obj.haveLayout()) {
|
||||
return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) };
|
||||
@ -3043,7 +3044,7 @@ pub const Type = extern union {
|
||||
const fields = ty.structFields();
|
||||
var big_align: u32 = 0;
|
||||
for (fields.values()) |field| {
|
||||
if (!(try field.ty.hasRuntimeBitsAdvanced(false, sema_kit))) continue;
|
||||
if (!(try field.ty.hasRuntimeBitsAdvanced(false, opt_sema))) continue;
|
||||
|
||||
const field_align = if (field.abi_align != 0)
|
||||
field.abi_align
|
||||
@ -3051,7 +3052,7 @@ pub const Type = extern union {
|
||||
.scalar => |a| a,
|
||||
.val => switch (strat) {
|
||||
.eager => unreachable, // struct layout not resolved
|
||||
.sema_kit => unreachable, // handled above
|
||||
.sema => unreachable, // handled above
|
||||
.lazy => |arena| return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) },
|
||||
},
|
||||
};
|
||||
@ -3080,7 +3081,7 @@ pub const Type = extern union {
|
||||
.scalar => |field_align| big_align = @max(big_align, field_align),
|
||||
.val => switch (strat) {
|
||||
.eager => unreachable, // field type alignment not resolved
|
||||
.sema_kit => unreachable, // passed to abiAlignmentAdvanced above
|
||||
.sema => unreachable, // passed to abiAlignmentAdvanced above
|
||||
.lazy => |arena| return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) },
|
||||
},
|
||||
}
|
||||
@ -3132,21 +3133,21 @@ pub const Type = extern union {
|
||||
union_obj: *Module.Union,
|
||||
have_tag: bool,
|
||||
) Module.CompileError!AbiAlignmentAdvanced {
|
||||
const sema_kit = switch (strat) {
|
||||
.sema_kit => |sk| sk,
|
||||
const opt_sema = switch (strat) {
|
||||
.sema => |sema| sema,
|
||||
else => null,
|
||||
};
|
||||
if (sema_kit) |sk| {
|
||||
if (opt_sema) |sema| {
|
||||
if (union_obj.status == .field_types_wip) {
|
||||
// We'll guess "pointer-aligned" and if we guess wrong, emit
|
||||
// a compile error later.
|
||||
return AbiAlignmentAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) };
|
||||
}
|
||||
_ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
|
||||
_ = try sema.resolveTypeFields(ty);
|
||||
}
|
||||
if (!union_obj.haveFieldTypes()) switch (strat) {
|
||||
.eager => unreachable, // union layout not resolved
|
||||
.sema_kit => unreachable, // handled above
|
||||
.sema => unreachable, // handled above
|
||||
.lazy => |arena| return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) },
|
||||
};
|
||||
if (union_obj.fields.count() == 0) {
|
||||
@ -3160,7 +3161,7 @@ pub const Type = extern union {
|
||||
var max_align: u32 = 0;
|
||||
if (have_tag) max_align = union_obj.tag_ty.abiAlignment(target);
|
||||
for (union_obj.fields.values()) |field| {
|
||||
if (!(try field.ty.hasRuntimeBitsAdvanced(false, sema_kit))) continue;
|
||||
if (!(try field.ty.hasRuntimeBitsAdvanced(false, opt_sema))) continue;
|
||||
|
||||
const field_align = if (field.abi_align != 0)
|
||||
field.abi_align
|
||||
@ -3168,7 +3169,7 @@ pub const Type = extern union {
|
||||
.scalar => |a| a,
|
||||
.val => switch (strat) {
|
||||
.eager => unreachable, // struct layout not resolved
|
||||
.sema_kit => unreachable, // handled above
|
||||
.sema => unreachable, // handled above
|
||||
.lazy => |arena| return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) },
|
||||
},
|
||||
};
|
||||
@ -3200,7 +3201,7 @@ pub const Type = extern union {
|
||||
/// In this case there will be no error, guaranteed.
|
||||
/// If you pass `lazy` you may get back `scalar` or `val`.
|
||||
/// If `val` is returned, a reference to `ty` has been captured.
|
||||
/// If you pass `sema_kit` you will get back `scalar` and resolve the type if
|
||||
/// If you pass `sema` you will get back `scalar` and resolve the type if
|
||||
/// necessary, possibly returning a CompileError.
|
||||
pub fn abiSizeAdvanced(
|
||||
ty: Type,
|
||||
@ -3243,7 +3244,7 @@ pub const Type = extern union {
|
||||
.Packed => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
switch (strat) {
|
||||
.sema_kit => |sk| try sk.sema.resolveTypeLayout(sk.block, sk.src, ty),
|
||||
.sema => |sema| try sema.resolveTypeLayout(ty),
|
||||
.lazy => |arena| {
|
||||
if (!struct_obj.haveLayout()) {
|
||||
return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) };
|
||||
@ -3256,7 +3257,7 @@ pub const Type = extern union {
|
||||
},
|
||||
else => {
|
||||
switch (strat) {
|
||||
.sema_kit => |sk| try sk.sema.resolveTypeLayout(sk.block, sk.src, ty),
|
||||
.sema => |sema| try sema.resolveTypeLayout(ty),
|
||||
.lazy => |arena| {
|
||||
if (ty.castTag(.@"struct")) |payload| {
|
||||
const struct_obj = payload.data;
|
||||
@ -3308,7 +3309,7 @@ pub const Type = extern union {
|
||||
switch (try payload.elem_type.abiSizeAdvanced(target, strat)) {
|
||||
.scalar => |elem_size| return AbiSizeAdvanced{ .scalar = payload.len * elem_size },
|
||||
.val => switch (strat) {
|
||||
.sema_kit => unreachable,
|
||||
.sema => unreachable,
|
||||
.eager => unreachable,
|
||||
.lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
|
||||
},
|
||||
@ -3319,7 +3320,7 @@ pub const Type = extern union {
|
||||
switch (try payload.elem_type.abiSizeAdvanced(target, strat)) {
|
||||
.scalar => |elem_size| return AbiSizeAdvanced{ .scalar = (payload.len + 1) * elem_size },
|
||||
.val => switch (strat) {
|
||||
.sema_kit => unreachable,
|
||||
.sema => unreachable,
|
||||
.eager => unreachable,
|
||||
.lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
|
||||
},
|
||||
@ -3328,14 +3329,14 @@ pub const Type = extern union {
|
||||
|
||||
.vector => {
|
||||
const payload = ty.castTag(.vector).?.data;
|
||||
const sema_kit = switch (strat) {
|
||||
.sema_kit => |sk| sk,
|
||||
const opt_sema = switch (strat) {
|
||||
.sema => |sema| sema,
|
||||
.eager => null,
|
||||
.lazy => |arena| return AbiSizeAdvanced{
|
||||
.val = try Value.Tag.lazy_size.create(arena, ty),
|
||||
},
|
||||
};
|
||||
const elem_bits = try payload.elem_type.bitSizeAdvanced(target, sema_kit);
|
||||
const elem_bits = try payload.elem_type.bitSizeAdvanced(target, opt_sema);
|
||||
const total_bits = elem_bits * payload.len;
|
||||
const total_bytes = (total_bits + 7) / 8;
|
||||
const alignment = switch (try ty.abiAlignmentAdvanced(target, strat)) {
|
||||
@ -3446,7 +3447,7 @@ pub const Type = extern union {
|
||||
const payload_size = switch (try child_type.abiSizeAdvanced(target, strat)) {
|
||||
.scalar => |elem_size| elem_size,
|
||||
.val => switch (strat) {
|
||||
.sema_kit => unreachable,
|
||||
.sema => unreachable,
|
||||
.eager => unreachable,
|
||||
.lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
|
||||
},
|
||||
@ -3475,7 +3476,7 @@ pub const Type = extern union {
|
||||
const payload_size = switch (try data.payload.abiSizeAdvanced(target, strat)) {
|
||||
.scalar => |elem_size| elem_size,
|
||||
.val => switch (strat) {
|
||||
.sema_kit => unreachable,
|
||||
.sema => unreachable,
|
||||
.eager => unreachable,
|
||||
.lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
|
||||
},
|
||||
@ -3506,7 +3507,7 @@ pub const Type = extern union {
|
||||
have_tag: bool,
|
||||
) Module.CompileError!AbiSizeAdvanced {
|
||||
switch (strat) {
|
||||
.sema_kit => |sk| try sk.sema.resolveTypeLayout(sk.block, sk.src, ty),
|
||||
.sema => |sema| try sema.resolveTypeLayout(ty),
|
||||
.lazy => |arena| {
|
||||
if (!union_obj.haveLayout()) {
|
||||
return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) };
|
||||
@ -3533,14 +3534,15 @@ pub const Type = extern union {
|
||||
return bitSizeAdvanced(ty, target, null) catch unreachable;
|
||||
}
|
||||
|
||||
/// If you pass `sema_kit`, any recursive type resolutions will happen if
|
||||
/// If you pass `opt_sema`, any recursive type resolutions will happen if
|
||||
/// necessary, possibly returning a CompileError. Passing `null` instead asserts
|
||||
/// the type is fully resolved, and there will be no error, guaranteed.
|
||||
pub fn bitSizeAdvanced(
|
||||
ty: Type,
|
||||
target: Target,
|
||||
sema_kit: ?Module.WipAnalysis,
|
||||
opt_sema: ?*Sema,
|
||||
) Module.CompileError!u64 {
|
||||
const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
|
||||
switch (ty.tag()) {
|
||||
.fn_noreturn_no_args => unreachable, // represents machine code; not a pointer
|
||||
.fn_void_no_args => unreachable, // represents machine code; not a pointer
|
||||
@ -3578,21 +3580,21 @@ pub const Type = extern union {
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
if (struct_obj.layout != .Packed) {
|
||||
return (try ty.abiSizeAdvanced(target, if (sema_kit) |sk| .{ .sema_kit = sk } else .eager)).scalar * 8;
|
||||
return (try ty.abiSizeAdvanced(target, strat)).scalar * 8;
|
||||
}
|
||||
if (sema_kit) |sk| _ = try sk.sema.resolveTypeLayout(sk.block, sk.src, ty);
|
||||
if (opt_sema) |sema| _ = try sema.resolveTypeLayout(ty);
|
||||
assert(struct_obj.haveLayout());
|
||||
return try struct_obj.backing_int_ty.bitSizeAdvanced(target, sema_kit);
|
||||
return try struct_obj.backing_int_ty.bitSizeAdvanced(target, opt_sema);
|
||||
},
|
||||
|
||||
.tuple, .anon_struct => {
|
||||
if (sema_kit) |sk| _ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
|
||||
if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
|
||||
if (ty.containerLayout() != .Packed) {
|
||||
return (try ty.abiSizeAdvanced(target, if (sema_kit) |sk| .{ .sema_kit = sk } else .eager)).scalar * 8;
|
||||
return (try ty.abiSizeAdvanced(target, strat)).scalar * 8;
|
||||
}
|
||||
var total: u64 = 0;
|
||||
for (ty.tupleFields().types) |field_ty| {
|
||||
total += try bitSizeAdvanced(field_ty, target, sema_kit);
|
||||
total += try bitSizeAdvanced(field_ty, target, opt_sema);
|
||||
}
|
||||
return total;
|
||||
},
|
||||
@ -3600,27 +3602,27 @@ pub const Type = extern union {
|
||||
.enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {
|
||||
var buffer: Payload.Bits = undefined;
|
||||
const int_tag_ty = ty.intTagType(&buffer);
|
||||
return try bitSizeAdvanced(int_tag_ty, target, sema_kit);
|
||||
return try bitSizeAdvanced(int_tag_ty, target, opt_sema);
|
||||
},
|
||||
|
||||
.@"union", .union_safety_tagged, .union_tagged => {
|
||||
if (sema_kit) |sk| _ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
|
||||
if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
|
||||
if (ty.containerLayout() != .Packed) {
|
||||
return (try ty.abiSizeAdvanced(target, if (sema_kit) |sk| .{ .sema_kit = sk } else .eager)).scalar * 8;
|
||||
return (try ty.abiSizeAdvanced(target, strat)).scalar * 8;
|
||||
}
|
||||
const union_obj = ty.cast(Payload.Union).?.data;
|
||||
assert(union_obj.haveFieldTypes());
|
||||
|
||||
var size: u64 = 0;
|
||||
for (union_obj.fields.values()) |field| {
|
||||
size = @max(size, try bitSizeAdvanced(field.ty, target, sema_kit));
|
||||
size = @max(size, try bitSizeAdvanced(field.ty, target, opt_sema));
|
||||
}
|
||||
return size;
|
||||
},
|
||||
|
||||
.vector => {
|
||||
const payload = ty.castTag(.vector).?.data;
|
||||
const elem_bit_size = try bitSizeAdvanced(payload.elem_type, target, sema_kit);
|
||||
const elem_bit_size = try bitSizeAdvanced(payload.elem_type, target, opt_sema);
|
||||
return elem_bit_size * payload.len;
|
||||
},
|
||||
.array_u8 => return 8 * ty.castTag(.array_u8).?.data,
|
||||
@ -3630,7 +3632,7 @@ pub const Type = extern union {
|
||||
const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
|
||||
if (elem_size == 0 or payload.len == 0)
|
||||
return @as(u64, 0);
|
||||
const elem_bit_size = try bitSizeAdvanced(payload.elem_type, target, sema_kit);
|
||||
const elem_bit_size = try bitSizeAdvanced(payload.elem_type, target, opt_sema);
|
||||
return (payload.len - 1) * 8 * elem_size + elem_bit_size;
|
||||
},
|
||||
.array_sentinel => {
|
||||
@ -3639,7 +3641,7 @@ pub const Type = extern union {
|
||||
payload.elem_type.abiAlignment(target),
|
||||
payload.elem_type.abiSize(target),
|
||||
);
|
||||
const elem_bit_size = try bitSizeAdvanced(payload.elem_type, target, sema_kit);
|
||||
const elem_bit_size = try bitSizeAdvanced(payload.elem_type, target, opt_sema);
|
||||
return payload.len * 8 * elem_size + elem_bit_size;
|
||||
},
|
||||
|
||||
@ -3706,7 +3708,7 @@ pub const Type = extern union {
|
||||
.optional, .error_union => {
|
||||
// Optionals and error unions are not packed so their bitsize
|
||||
// includes padding bits.
|
||||
return (try abiSizeAdvanced(ty, target, if (sema_kit) |sk| .{ .sema_kit = sk } else .eager)).scalar * 8;
|
||||
return (try abiSizeAdvanced(ty, target, strat)).scalar * 8;
|
||||
},
|
||||
|
||||
.atomic_order,
|
||||
|
||||
112
src/value.zig
112
src/value.zig
@ -1099,7 +1099,7 @@ pub const Value = extern union {
|
||||
val: Value,
|
||||
space: *BigIntSpace,
|
||||
target: Target,
|
||||
sema_kit: ?Module.WipAnalysis,
|
||||
opt_sema: ?*Sema,
|
||||
) Module.CompileError!BigIntConst {
|
||||
switch (val.tag()) {
|
||||
.null_value,
|
||||
@ -1121,16 +1121,16 @@ pub const Value = extern union {
|
||||
|
||||
.lazy_align => {
|
||||
const ty = val.castTag(.lazy_align).?.data;
|
||||
if (sema_kit) |sk| {
|
||||
try sk.sema.resolveTypeLayout(sk.block, sk.src, ty);
|
||||
if (opt_sema) |sema| {
|
||||
try sema.resolveTypeLayout(ty);
|
||||
}
|
||||
const x = ty.abiAlignment(target);
|
||||
return BigIntMutable.init(&space.limbs, x).toConst();
|
||||
},
|
||||
.lazy_size => {
|
||||
const ty = val.castTag(.lazy_size).?.data;
|
||||
if (sema_kit) |sk| {
|
||||
try sk.sema.resolveTypeLayout(sk.block, sk.src, ty);
|
||||
if (opt_sema) |sema| {
|
||||
try sema.resolveTypeLayout(ty);
|
||||
}
|
||||
const x = ty.abiSize(target);
|
||||
return BigIntMutable.init(&space.limbs, x).toConst();
|
||||
@ -1138,7 +1138,7 @@ pub const Value = extern union {
|
||||
|
||||
.elem_ptr => {
|
||||
const elem_ptr = val.castTag(.elem_ptr).?.data;
|
||||
const array_addr = (try elem_ptr.array_ptr.getUnsignedIntAdvanced(target, sema_kit)).?;
|
||||
const array_addr = (try elem_ptr.array_ptr.getUnsignedIntAdvanced(target, opt_sema)).?;
|
||||
const elem_size = elem_ptr.elem_ty.abiSize(target);
|
||||
const new_addr = array_addr + elem_size * elem_ptr.index;
|
||||
return BigIntMutable.init(&space.limbs, new_addr).toConst();
|
||||
@ -1156,7 +1156,7 @@ pub const Value = extern union {
|
||||
|
||||
/// If the value fits in a u64, return it, otherwise null.
|
||||
/// Asserts not undefined.
|
||||
pub fn getUnsignedIntAdvanced(val: Value, target: Target, sema_kit: ?Module.WipAnalysis) !?u64 {
|
||||
pub fn getUnsignedIntAdvanced(val: Value, target: Target, opt_sema: ?*Sema) !?u64 {
|
||||
switch (val.tag()) {
|
||||
.zero,
|
||||
.bool_false,
|
||||
@ -1176,16 +1176,16 @@ pub const Value = extern union {
|
||||
|
||||
.lazy_align => {
|
||||
const ty = val.castTag(.lazy_align).?.data;
|
||||
if (sema_kit) |sk| {
|
||||
return (try ty.abiAlignmentAdvanced(target, .{ .sema_kit = sk })).scalar;
|
||||
if (opt_sema) |sema| {
|
||||
return (try ty.abiAlignmentAdvanced(target, .{ .sema = sema })).scalar;
|
||||
} else {
|
||||
return ty.abiAlignment(target);
|
||||
}
|
||||
},
|
||||
.lazy_size => {
|
||||
const ty = val.castTag(.lazy_size).?.data;
|
||||
if (sema_kit) |sk| {
|
||||
return (try ty.abiSizeAdvanced(target, .{ .sema_kit = sk })).scalar;
|
||||
if (opt_sema) |sema| {
|
||||
return (try ty.abiSizeAdvanced(target, .{ .sema = sema })).scalar;
|
||||
} else {
|
||||
return ty.abiSize(target);
|
||||
}
|
||||
@ -1886,7 +1886,7 @@ pub const Value = extern union {
|
||||
|
||||
pub fn orderAgainstZeroAdvanced(
|
||||
lhs: Value,
|
||||
sema_kit: ?Module.WipAnalysis,
|
||||
opt_sema: ?*Sema,
|
||||
) Module.CompileError!std.math.Order {
|
||||
return switch (lhs.tag()) {
|
||||
.zero,
|
||||
@ -1911,7 +1911,7 @@ pub const Value = extern union {
|
||||
|
||||
.lazy_align => {
|
||||
const ty = lhs.castTag(.lazy_align).?.data;
|
||||
if (try ty.hasRuntimeBitsAdvanced(false, sema_kit)) {
|
||||
if (try ty.hasRuntimeBitsAdvanced(false, opt_sema)) {
|
||||
return .gt;
|
||||
} else {
|
||||
return .eq;
|
||||
@ -1919,7 +1919,7 @@ pub const Value = extern union {
|
||||
},
|
||||
.lazy_size => {
|
||||
const ty = lhs.castTag(.lazy_size).?.data;
|
||||
if (try ty.hasRuntimeBitsAdvanced(false, sema_kit)) {
|
||||
if (try ty.hasRuntimeBitsAdvanced(false, opt_sema)) {
|
||||
return .gt;
|
||||
} else {
|
||||
return .eq;
|
||||
@ -1934,7 +1934,7 @@ pub const Value = extern union {
|
||||
|
||||
.elem_ptr => {
|
||||
const elem_ptr = lhs.castTag(.elem_ptr).?.data;
|
||||
switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(sema_kit)) {
|
||||
switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(opt_sema)) {
|
||||
.lt => unreachable,
|
||||
.gt => return .gt,
|
||||
.eq => {
|
||||
@ -1957,12 +1957,12 @@ pub const Value = extern union {
|
||||
}
|
||||
|
||||
/// Asserts the value is comparable.
|
||||
/// If sema_kit is null then this function asserts things are resolved and cannot fail.
|
||||
pub fn orderAdvanced(lhs: Value, rhs: Value, target: Target, sema_kit: ?Module.WipAnalysis) !std.math.Order {
|
||||
/// If opt_sema is null then this function asserts things are resolved and cannot fail.
|
||||
pub fn orderAdvanced(lhs: Value, rhs: Value, target: Target, opt_sema: ?*Sema) !std.math.Order {
|
||||
const lhs_tag = lhs.tag();
|
||||
const rhs_tag = rhs.tag();
|
||||
const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(sema_kit);
|
||||
const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(sema_kit);
|
||||
const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(opt_sema);
|
||||
const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(opt_sema);
|
||||
switch (lhs_against_zero) {
|
||||
.lt => if (rhs_against_zero != .lt) return .lt,
|
||||
.eq => return rhs_against_zero.invert(),
|
||||
@ -1996,8 +1996,8 @@ pub const Value = extern union {
|
||||
|
||||
var lhs_bigint_space: BigIntSpace = undefined;
|
||||
var rhs_bigint_space: BigIntSpace = undefined;
|
||||
const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, target, sema_kit);
|
||||
const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, target, sema_kit);
|
||||
const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, target, opt_sema);
|
||||
const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, target, opt_sema);
|
||||
return lhs_bigint.order(rhs_bigint);
|
||||
}
|
||||
|
||||
@ -2012,7 +2012,7 @@ pub const Value = extern union {
|
||||
op: std.math.CompareOperator,
|
||||
rhs: Value,
|
||||
target: Target,
|
||||
sema_kit: ?Module.WipAnalysis,
|
||||
opt_sema: ?*Sema,
|
||||
) !bool {
|
||||
if (lhs.pointerDecl()) |lhs_decl| {
|
||||
if (rhs.pointerDecl()) |rhs_decl| {
|
||||
@ -2035,7 +2035,7 @@ pub const Value = extern union {
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
return (try orderAdvanced(lhs, rhs, target, sema_kit)).compare(op);
|
||||
return (try orderAdvanced(lhs, rhs, target, opt_sema)).compare(op);
|
||||
}
|
||||
|
||||
/// Asserts the values are comparable. Both operands have type `ty`.
|
||||
@ -2079,13 +2079,13 @@ pub const Value = extern union {
|
||||
pub fn compareAllWithZeroAdvanced(
|
||||
lhs: Value,
|
||||
op: std.math.CompareOperator,
|
||||
sema_kit: ?Module.WipAnalysis,
|
||||
opt_sema: ?*Sema,
|
||||
) Module.CompileError!bool {
|
||||
switch (lhs.tag()) {
|
||||
.repeated => return lhs.castTag(.repeated).?.data.compareAllWithZeroAdvanced(op, sema_kit),
|
||||
.repeated => return lhs.castTag(.repeated).?.data.compareAllWithZeroAdvanced(op, opt_sema),
|
||||
.aggregate => {
|
||||
for (lhs.castTag(.aggregate).?.data) |elem_val| {
|
||||
if (!(try elem_val.compareAllWithZeroAdvanced(op, sema_kit))) return false;
|
||||
if (!(try elem_val.compareAllWithZeroAdvanced(op, opt_sema))) return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@ -2096,7 +2096,7 @@ pub const Value = extern union {
|
||||
.float_128 => if (std.math.isNan(lhs.castTag(.float_128).?.data)) return op != .neq,
|
||||
else => {},
|
||||
}
|
||||
return (try orderAgainstZeroAdvanced(lhs, sema_kit)).compare(op);
|
||||
return (try orderAgainstZeroAdvanced(lhs, opt_sema)).compare(op);
|
||||
}
|
||||
|
||||
pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {
|
||||
@ -2111,14 +2111,14 @@ pub const Value = extern union {
|
||||
/// for `a`. This function must act *as if* `a` has been coerced to `ty`. This complication
|
||||
/// is required in order to make generic function instantiation efficient - specifically
|
||||
/// the insertion into the monomorphized function table.
|
||||
/// If `null` is provided for `sema_kit` then it is guaranteed no error will be returned.
|
||||
/// If `null` is provided for `opt_sema` then it is guaranteed no error will be returned.
|
||||
pub fn eqlAdvanced(
|
||||
a: Value,
|
||||
a_ty: Type,
|
||||
b: Value,
|
||||
ty: Type,
|
||||
mod: *Module,
|
||||
sema_kit: ?Module.WipAnalysis,
|
||||
opt_sema: ?*Sema,
|
||||
) Module.CompileError!bool {
|
||||
const target = mod.getTarget();
|
||||
const a_tag = a.tag();
|
||||
@ -2141,33 +2141,33 @@ pub const Value = extern union {
|
||||
const b_payload = b.castTag(.opt_payload).?.data;
|
||||
var buffer: Type.Payload.ElemType = undefined;
|
||||
const payload_ty = ty.optionalChild(&buffer);
|
||||
return eqlAdvanced(a_payload, payload_ty, b_payload, payload_ty, mod, sema_kit);
|
||||
return eqlAdvanced(a_payload, payload_ty, b_payload, payload_ty, mod, opt_sema);
|
||||
},
|
||||
.slice => {
|
||||
const a_payload = a.castTag(.slice).?.data;
|
||||
const b_payload = b.castTag(.slice).?.data;
|
||||
if (!(try eqlAdvanced(a_payload.len, Type.usize, b_payload.len, Type.usize, mod, sema_kit))) {
|
||||
if (!(try eqlAdvanced(a_payload.len, Type.usize, b_payload.len, Type.usize, mod, opt_sema))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
|
||||
const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
|
||||
|
||||
return eqlAdvanced(a_payload.ptr, ptr_ty, b_payload.ptr, ptr_ty, mod, sema_kit);
|
||||
return eqlAdvanced(a_payload.ptr, ptr_ty, b_payload.ptr, ptr_ty, mod, opt_sema);
|
||||
},
|
||||
.elem_ptr => {
|
||||
const a_payload = a.castTag(.elem_ptr).?.data;
|
||||
const b_payload = b.castTag(.elem_ptr).?.data;
|
||||
if (a_payload.index != b_payload.index) return false;
|
||||
|
||||
return eqlAdvanced(a_payload.array_ptr, ty, b_payload.array_ptr, ty, mod, sema_kit);
|
||||
return eqlAdvanced(a_payload.array_ptr, ty, b_payload.array_ptr, ty, mod, opt_sema);
|
||||
},
|
||||
.field_ptr => {
|
||||
const a_payload = a.castTag(.field_ptr).?.data;
|
||||
const b_payload = b.castTag(.field_ptr).?.data;
|
||||
if (a_payload.field_index != b_payload.field_index) return false;
|
||||
|
||||
return eqlAdvanced(a_payload.container_ptr, ty, b_payload.container_ptr, ty, mod, sema_kit);
|
||||
return eqlAdvanced(a_payload.container_ptr, ty, b_payload.container_ptr, ty, mod, opt_sema);
|
||||
},
|
||||
.@"error" => {
|
||||
const a_name = a.castTag(.@"error").?.data.name;
|
||||
@ -2178,7 +2178,7 @@ pub const Value = extern union {
|
||||
const a_payload = a.castTag(.eu_payload).?.data;
|
||||
const b_payload = b.castTag(.eu_payload).?.data;
|
||||
const payload_ty = ty.errorUnionPayload();
|
||||
return eqlAdvanced(a_payload, payload_ty, b_payload, payload_ty, mod, sema_kit);
|
||||
return eqlAdvanced(a_payload, payload_ty, b_payload, payload_ty, mod, opt_sema);
|
||||
},
|
||||
.eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
|
||||
.opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
|
||||
@ -2196,7 +2196,7 @@ pub const Value = extern union {
|
||||
const types = ty.tupleFields().types;
|
||||
assert(types.len == a_field_vals.len);
|
||||
for (types) |field_ty, i| {
|
||||
if (!(try eqlAdvanced(a_field_vals[i], field_ty, b_field_vals[i], field_ty, mod, sema_kit))) {
|
||||
if (!(try eqlAdvanced(a_field_vals[i], field_ty, b_field_vals[i], field_ty, mod, opt_sema))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2207,7 +2207,7 @@ pub const Value = extern union {
|
||||
const fields = ty.structFields().values();
|
||||
assert(fields.len == a_field_vals.len);
|
||||
for (fields) |field, i| {
|
||||
if (!(try eqlAdvanced(a_field_vals[i], field.ty, b_field_vals[i], field.ty, mod, sema_kit))) {
|
||||
if (!(try eqlAdvanced(a_field_vals[i], field.ty, b_field_vals[i], field.ty, mod, opt_sema))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2218,7 +2218,7 @@ pub const Value = extern union {
|
||||
for (a_field_vals) |a_elem, i| {
|
||||
const b_elem = b_field_vals[i];
|
||||
|
||||
if (!(try eqlAdvanced(a_elem, elem_ty, b_elem, elem_ty, mod, sema_kit))) {
|
||||
if (!(try eqlAdvanced(a_elem, elem_ty, b_elem, elem_ty, mod, opt_sema))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2230,7 +2230,7 @@ pub const Value = extern union {
|
||||
switch (ty.containerLayout()) {
|
||||
.Packed, .Extern => {
|
||||
const tag_ty = ty.unionTagTypeHypothetical();
|
||||
if (!(try eqlAdvanced(a_union.tag, tag_ty, b_union.tag, tag_ty, mod, sema_kit))) {
|
||||
if (!(try eqlAdvanced(a_union.tag, tag_ty, b_union.tag, tag_ty, mod, opt_sema))) {
|
||||
// In this case, we must disregard mismatching tags and compare
|
||||
// based on the in-memory bytes of the payloads.
|
||||
@panic("TODO comptime comparison of extern union values with mismatching tags");
|
||||
@ -2238,13 +2238,13 @@ pub const Value = extern union {
|
||||
},
|
||||
.Auto => {
|
||||
const tag_ty = ty.unionTagTypeHypothetical();
|
||||
if (!(try eqlAdvanced(a_union.tag, tag_ty, b_union.tag, tag_ty, mod, sema_kit))) {
|
||||
if (!(try eqlAdvanced(a_union.tag, tag_ty, b_union.tag, tag_ty, mod, opt_sema))) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
}
|
||||
const active_field_ty = ty.unionFieldType(a_union.tag, mod);
|
||||
return eqlAdvanced(a_union.val, active_field_ty, b_union.val, active_field_ty, mod, sema_kit);
|
||||
return eqlAdvanced(a_union.val, active_field_ty, b_union.val, active_field_ty, mod, opt_sema);
|
||||
},
|
||||
else => {},
|
||||
} else if (b_tag == .null_value or b_tag == .@"error") {
|
||||
@ -2278,7 +2278,7 @@ pub const Value = extern union {
|
||||
const b_val = b.enumToInt(ty, &buf_b);
|
||||
var buf_ty: Type.Payload.Bits = undefined;
|
||||
const int_ty = ty.intTagType(&buf_ty);
|
||||
return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, sema_kit);
|
||||
return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema);
|
||||
},
|
||||
.Array, .Vector => {
|
||||
const len = ty.arrayLen();
|
||||
@ -2289,7 +2289,7 @@ pub const Value = extern union {
|
||||
while (i < len) : (i += 1) {
|
||||
const a_elem = elemValueBuffer(a, mod, i, &a_buf);
|
||||
const b_elem = elemValueBuffer(b, mod, i, &b_buf);
|
||||
if (!(try eqlAdvanced(a_elem, elem_ty, b_elem, elem_ty, mod, sema_kit))) {
|
||||
if (!(try eqlAdvanced(a_elem, elem_ty, b_elem, elem_ty, mod, opt_sema))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2313,7 +2313,7 @@ pub const Value = extern union {
|
||||
.One => a,
|
||||
else => unreachable,
|
||||
};
|
||||
return try eqlAdvanced(a_ptr, ptr_ty, b.slicePtr(), ptr_ty, mod, sema_kit);
|
||||
return try eqlAdvanced(a_ptr, ptr_ty, b.slicePtr(), ptr_ty, mod, opt_sema);
|
||||
},
|
||||
.Many, .C, .One => {},
|
||||
},
|
||||
@ -2346,7 +2346,7 @@ pub const Value = extern union {
|
||||
const field_tag = Value.initPayload(&field_tag_buf.base);
|
||||
const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);
|
||||
if (!tag_matches) return false;
|
||||
return eqlAdvanced(tag_and_val.val, union_obj.tag_ty, tuple.values[0], tuple.types[0], mod, sema_kit);
|
||||
return eqlAdvanced(tag_and_val.val, union_obj.tag_ty, tuple.values[0], tuple.types[0], mod, opt_sema);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
@ -2377,7 +2377,7 @@ pub const Value = extern union {
|
||||
.data = a,
|
||||
};
|
||||
const sub_val = Value.initPayload(&sub_pl.base);
|
||||
return eqlAdvanced(sub_val, ty, b, ty, mod, sema_kit);
|
||||
return eqlAdvanced(sub_val, ty, b, ty, mod, opt_sema);
|
||||
},
|
||||
.ErrorUnion => if (a_tag != .@"error" and b_tag == .eu_payload) {
|
||||
var sub_pl: Payload.SubValue = .{
|
||||
@ -2385,12 +2385,12 @@ pub const Value = extern union {
|
||||
.data = a,
|
||||
};
|
||||
const sub_val = Value.initPayload(&sub_pl.base);
|
||||
return eqlAdvanced(sub_val, ty, b, ty, mod, sema_kit);
|
||||
return eqlAdvanced(sub_val, ty, b, ty, mod, opt_sema);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
if (a_tag == .null_value or a_tag == .@"error") return false;
|
||||
return (try orderAdvanced(a, b, target, sema_kit)).compare(.eq);
|
||||
return (try orderAdvanced(a, b, target, opt_sema)).compare(.eq);
|
||||
}
|
||||
|
||||
/// This function is used by hash maps and so treats floating-point NaNs as equal
|
||||
@ -3161,18 +3161,18 @@ pub const Value = extern union {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn intToFloatAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, target: Target, sema_kit: ?Module.WipAnalysis) !Value {
|
||||
pub fn intToFloatAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, target: Target, opt_sema: ?*Sema) !Value {
|
||||
if (int_ty.zigTypeTag() == .Vector) {
|
||||
const result_data = try arena.alloc(Value, int_ty.vectorLen());
|
||||
for (result_data) |*scalar, i| {
|
||||
scalar.* = try intToFloatScalar(val.indexVectorlike(i), arena, float_ty.scalarType(), target, sema_kit);
|
||||
scalar.* = try intToFloatScalar(val.indexVectorlike(i), arena, float_ty.scalarType(), target, opt_sema);
|
||||
}
|
||||
return Value.Tag.aggregate.create(arena, result_data);
|
||||
}
|
||||
return intToFloatScalar(val, arena, float_ty, target, sema_kit);
|
||||
return intToFloatScalar(val, arena, float_ty, target, opt_sema);
|
||||
}
|
||||
|
||||
pub fn intToFloatScalar(val: Value, arena: Allocator, float_ty: Type, target: Target, sema_kit: ?Module.WipAnalysis) !Value {
|
||||
pub fn intToFloatScalar(val: Value, arena: Allocator, float_ty: Type, target: Target, opt_sema: ?*Sema) !Value {
|
||||
switch (val.tag()) {
|
||||
.undef, .zero, .one => return val,
|
||||
.the_only_possible_value => return Value.initTag(.zero), // for i0, u0
|
||||
@ -3194,16 +3194,16 @@ pub const Value = extern union {
|
||||
},
|
||||
.lazy_align => {
|
||||
const ty = val.castTag(.lazy_align).?.data;
|
||||
if (sema_kit) |sk| {
|
||||
return intToFloatInner((try ty.abiAlignmentAdvanced(target, .{ .sema_kit = sk })).scalar, arena, float_ty, target);
|
||||
if (opt_sema) |sema| {
|
||||
return intToFloatInner((try ty.abiAlignmentAdvanced(target, .{ .sema = sema })).scalar, arena, float_ty, target);
|
||||
} else {
|
||||
return intToFloatInner(ty.abiAlignment(target), arena, float_ty, target);
|
||||
}
|
||||
},
|
||||
.lazy_size => {
|
||||
const ty = val.castTag(.lazy_size).?.data;
|
||||
if (sema_kit) |sk| {
|
||||
return intToFloatInner((try ty.abiSizeAdvanced(target, .{ .sema_kit = sk })).scalar, arena, float_ty, target);
|
||||
if (opt_sema) |sema| {
|
||||
return intToFloatInner((try ty.abiSizeAdvanced(target, .{ .sema = sema })).scalar, arena, float_ty, target);
|
||||
} else {
|
||||
return intToFloatInner(ty.abiSize(target), arena, float_ty, target);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user