diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2024-12-06 08:15:46 +0000 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2024-12-08 10:53:50 +0000 |
| commit | 03f5b967f0d0dcdcb850061613cdb0793e2d8be2 (patch) | |
| tree | b24253b9f2c865e5564e1503f3533c170df1bd58 /src/codegen/spirv/Section.zig | |
| parent | e62aac3ec4b21da20d7c57d937e508f2929138d0 (diff) | |
| download | zig-03f5b967f0d0dcdcb850061613cdb0793e2d8be2.tar.gz zig-03f5b967f0d0dcdcb850061613cdb0793e2d8be2.zip | |
AstGen: correctly deduplicate `ref` of `param` and `alloc_inferred`
Both of these instructions were previously under a special case in
`rvalue` which resulted in every reference to such an instruction adding
a new `ref` instruction. This had the effect that, for instance,
`&a != &a` for parameters. Deduplicating these `ref` instructions was
problematic for different reasons.
For `alloc_inferred`, the problem was that it's not valid to `ref` the
alloc until the allocation has been resolved (`resolve_inferred_alloc`),
but `AstGen.appendBodyWithFixups` would place the `ref` directly after
the `alloc_inferred`. This is solved by bringing
`resolve_inferred_alloc` in line with `make_ptr_const` by having it
*return* the final pointer, rather than modifying `sema.inst_map` of the
original `alloc_inferred`. That way, the `ref` refers to the
`resolve_inferred_alloc` instruction, so is placed immediately after it,
avoiding this issue.
For `param`, the problem is a bit trickier: `param` instructions live in
a body which must contain only `param` instructions, then a
`func{,_inferred,_fancy}`, then a `break_inline`. Moreover, `param`
instructions may be referenced not only by the function body, but also
by other parameters, the return type expression, etc. Each of these
bodies requires separate `ref` instructions. This is solved by pulling
entries out of `ref_table` after evaluating each component of the
function declaration, and appending the refs later on when actually
putting the bodies together. This gives way to another issue: if you
write `fn f(x: T) @TypeOf(x.foo())`, then since `x.foo()` takes a
reference to `x`, this `ref` instruction is now in a comptime context
(outside of the `@TypeOf` ZIR body), so emits a compile error. This is
solved by loosening the rules around `ref` instructions; because they
are not side-effecting, it is okay to allow `ref` of runtime values at
comptime, resulting in a runtime-known value in a comptime scope. We
already apply this mechanism in some cases; for instance, it's why
`runtime_array.len` works in a `comptime` context. In future, we will
want to give similar treatment to many operations in Sema: in general,
it's fine to apply runtime operations at comptime provided they don't
have side effects!
Resolves: #22140
Diffstat (limited to 'src/codegen/spirv/Section.zig')
0 files changed, 0 insertions, 0 deletions
