diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-02-27 16:51:33 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-02-27 16:51:33 -0700 |
| commit | 9d4cfd9048d71d7519d759b9849914ce154d1877 (patch) | |
| tree | e28008bbb3ff86babf48fbe4b80d078e9217c2f3 /src/Sema.zig | |
| parent | 71aa5084edd1d3fba5bf8db87c4cf0d03667a566 (diff) | |
| download | zig-9d4cfd9048d71d7519d759b9849914ce154d1877.tar.gz zig-9d4cfd9048d71d7519d759b9849914ce154d1877.zip | |
Sema: resolve necessary information ahead of time
Do the fallible logic in Sema where we have access to error reporting
mechanisms, rather than in Type/Value.
We can't just do the best guess when resolving queries of "is this type
comptime only?" or "what is the ABI alignment of this field?". The
result needs to be accurate. So we need to keep the assertions that the
data is available active, and instead compute the necessary information
before such functions get called.
Unfortunately we are stuck with two versions of such functions because
the various backends need to be able to ask such queries of Types and
Values while assuming the result has already been computed and validated
by Sema.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 4a8cd38dd4..7f32444774 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -10402,7 +10402,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const union_field_fields = try fields_anon_decl.arena().create([3]Value); const alignment = switch (layout) { - .Auto, .Extern => field.normalAlignment(target), + .Auto, .Extern => try sema.unionFieldAlignment(block, src, field), .Packed => 0, }; @@ -17713,6 +17713,10 @@ fn resolveTypeLayout( .Optional => { var buf: Type.Payload.ElemType = undefined; const payload_ty = ty.optionalChild(&buf); + // In case of querying the ABI alignment of this optional, we will ask + // for hasRuntimeBits() of the payload type, so we need "requires comptime" + // to be known already before this function returns. + _ = try sema.typeRequiresComptime(block, src, payload_ty); return sema.resolveTypeLayout(block, src, payload_ty); }, .ErrorUnion => { @@ -17744,6 +17748,13 @@ fn resolveStructLayout( try sema.resolveTypeLayout(block, src, field.ty); } struct_obj.status = .have_layout; + + // In case of querying the ABI alignment of this struct, we will ask + // for hasRuntimeBits() of each field, so we need "requires comptime" + // to be known already before this function returns. + for (struct_obj.fields.values()) |field| { + _ = try sema.typeRequiresComptime(block, src, field.ty); + } } // otherwise it's a tuple; no need to resolve anything } @@ -19297,6 +19308,21 @@ fn typeAbiAlignment(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u32 return ty.abiAlignment(target); } +/// Not valid to call for packed unions. +/// Keep implementation in sync with `Module.Union.Field.normalAlignment`. +fn unionFieldAlignment( + sema: *Sema, + block: *Block, + src: LazySrcLoc, + field: Module.Union.Field, +) !u32 { + if (field.abi_align.tag() == .abi_align_default) { + return sema.typeAbiAlignment(block, src, field.ty); + } else { + return @intCast(u32, field.abi_align.toUnsignedInt()); + } +} + /// Synchronize logic with `Type.isFnOrHasRuntimeBits`. pub fn fnHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { const fn_info = ty.fnInfo(); |
