Restructure handling of expressions in patterns (#7445)

Instead of maintaining a stack of pending subpatterns which might or
might not contain expressions, we mark non-nesting regions during
pattern handling that might contain an expression. The implementation
remains largely the same; the difference is that callers are expected to
end a pending expression region as soon as possible, rather than wait
for the end of the subpattern. This makes it possible to emit
non-pattern insts during pattern handling, without the risk that they
will get caught in a pending expression region further up the stack.
This commit is contained in:
Geoff Romer
2026-07-01 19:15:34 +00:00
committed by GitHub
parent e7771c2f6d
commit 11eaeeda7d
10 changed files with 99 additions and 71 deletions
+7 -7
View File
@@ -1473,7 +1473,7 @@ static auto MakeSelfParamPatternBlockId(
const auto* method_decl = cast<clang::CXXMethodDecl>(&clang_decl);
// Build a `self` parameter from the object parameter.
BeginSubpattern(context);
BeginExprRegionForPattern(context);
clang::QualType param_type =
method_decl->getFunctionObjectParameterReferenceType();
@@ -1483,9 +1483,9 @@ static auto MakeSelfParamPatternBlockId(
auto param_info = MapParameterType(context, loc_id, param_type, passing_mode);
auto [type_inst_id, type_id] = param_info.type;
SemIR::ExprRegionId type_expr_region_id =
ConsumeSubpatternExpr(context, type_inst_id);
ConsumeExprRegionForPattern(context, type_inst_id);
EndEmptySubpattern(context);
EndEmptyExprRegionForPattern(context);
if (!type_id.has_value()) {
context.TODO(loc_id,
@@ -1538,8 +1538,8 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id,
ClangGetUnqualifiedTypePreserveNonNull(context, orig_param_type);
// Mark the start of a region of insts, needed for the type expression
// created later with the call of `ConsumeSubpatternExpr()`.
BeginSubpattern(context);
// created later with the call of `ConsumeExprRegionForPattern()`.
BeginExprRegionForPattern(context);
auto param_info = MapParameterType(context, loc_id, param_type,
signature.GetPassingMode(i));
auto [type_inst_id, type_id] = param_info.type;
@@ -1547,8 +1547,8 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id,
// region that allows control flow in the type expression e.g. fn F(x: if C
// then i32 else i64).
SemIR::ExprRegionId type_expr_region_id =
ConsumeSubpatternExpr(context, type_inst_id);
EndEmptySubpattern(context);
ConsumeExprRegionForPattern(context, type_inst_id);
EndEmptyExprRegionForPattern(context);
if (!type_id.has_value()) {
context.TODO(loc_id, llvm::formatv("Unsupported: parameter type: {0}",