AstGen: correctly deduplicate ref
of param
and alloc_inferred
#22164
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Both of these instructions were previously under a special case in
rvalue
which resulted in every reference to such an instruction adding a newref
instruction. This had the effect that, for instance,&a != &a
for parameters. Deduplicating theseref
instructions was problematic for different reasons.For
alloc_inferred
, the problem was that it's not valid toref
the alloc until the allocation has been resolved (resolve_inferred_alloc
), butAstGen.appendBodyWithFixups
would place theref
directly after thealloc_inferred
. This is solved by bringingresolve_inferred_alloc
in line withmake_ptr_const
by having it return the final pointer, rather than modifyingsema.inst_map
of the originalalloc_inferred
. That way, theref
refers to theresolve_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 onlyparam
instructions, then afunc{,_inferred,_fancy}
, then abreak_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 separateref
instructions. This is solved by pulling entries out ofref_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 writefn f(x: T) @TypeOf(x.foo())
, then sincex.foo()
takes a reference tox
, thisref
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 aroundref
instructions; because they are not side-effecting, it is okay to allowref
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 whyruntime_array.len
works in acomptime
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