Build VarStorage insts more efficiently. (#7422)

Instead of traversing the entire pattern block looking for
`VarPattern`s, we keep track of them on creation, and then build
`VarStorage`s directly from that list.

This also gets rid of the global `var_storage_map`, and instead keep
that information narrowly scoped to each full-pattern, and consume it in
a single linear traversal instead of with random-access lookups. To
enable that, this fixes a parse bug where nested `var` patterns were
getting diagnosed but not marked as errors.
This commit is contained in:
Geoff Romer
2026-06-26 22:26:13 +00:00
committed by GitHub
parent cfd1ed8484
commit 1a3966d2c4
14 changed files with 176 additions and 188 deletions
+2 -20
View File
@@ -206,11 +206,8 @@ auto AddBindingPattern(Context& context, SemIR::LocId name_loc,
return {.pattern_id = binding_pattern_id, .bind_id = bind_id};
}
// Returns a VarStorage inst for the given `var` pattern. If the pattern
// is the body of a returned var, this reuses the return parameter, and
// otherwise it adds a new inst.
static auto GetOrAddVarStorage(Context& context, SemIR::InstId var_pattern_id,
bool is_returned_var) -> SemIR::InstId {
auto GetOrAddVarStorage(Context& context, SemIR::InstId var_pattern_id,
bool is_returned_var) -> SemIR::InstId {
if (is_returned_var) {
if (auto return_param_id =
GetReturnedVarParam(context, GetCurrentFunctionForReturn(context));
@@ -227,21 +224,6 @@ static auto GetOrAddVarStorage(Context& context, SemIR::InstId var_pattern_id,
.pattern_id = var_pattern_id});
}
auto AddPatternVarStorage(Context& context, SemIR::InstBlockId pattern_block_id,
bool is_returned_var) -> void {
// We need to emit the VarStorage insts early, because they may be output
// arguments for the initializer. However, we can't emit them when we emit
// the corresponding `AnyVarPattern`s because they're part of the pattern
// match, not part of the pattern.
// TODO: Find a way to do this without walking the whole pattern block.
for (auto inst_id : context.inst_blocks().Get(pattern_block_id)) {
if (context.insts().Is<SemIR::AnyVarPattern>(inst_id)) {
context.var_storage_map().Insert(
inst_id, GetOrAddVarStorage(context, inst_id, is_returned_var));
}
}
}
auto GetParamPatternKind(Context& context, SemIR::InstId param_inst_id)
-> ParamPatternKind {
auto param = context.insts().Get(