Add support for ->? return forms (#6849)

This includes checking and lowering for concrete form literals. Support
for symbolic forms is future work.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Geoff Romer
2026-03-09 22:30:16 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent 5ad9b1a35d
commit 18cfeb7476
19 changed files with 574 additions and 75 deletions
+14 -8
View File
@@ -35,9 +35,11 @@ auto FindSelfPattern(Context& context,
auto AddReturnPatterns(Context& context, SemIR::LocId loc_id,
Context::FormExpr form_expr) -> SemIR::InstBlockId {
llvm::SmallVector<SemIR::InstId, 1> return_patterns;
auto form_inst = context.insts().Get(form_expr.form_inst_id);
auto form_inst = context.insts().Get(
context.constant_values().GetConstantInstId(form_expr.form_inst_id));
CARBON_KIND_SWITCH(form_inst) {
case SemIR::RefForm::Kind: {
case SemIR::RefForm::Kind:
case SemIR::ValueForm::Kind: {
break;
}
case CARBON_KIND(SemIR::InitForm _): {
@@ -56,6 +58,11 @@ auto AddReturnPatterns(Context& context, SemIR::LocId loc_id,
case SemIR::ErrorInst::Kind: {
break;
}
case SemIR::SymbolicBinding::Kind:
CARBON_CHECK(
context.constant_values().Get(form_expr.form_inst_id).is_symbolic());
context.TODO(loc_id, "Support symbolic return forms");
break;
default:
CARBON_FATAL("unexpected inst kind: {0}", form_inst);
}
@@ -115,8 +122,7 @@ static auto MakeFunctionSignature(Context& context, SemIR::LocId loc_id,
// Build and add a `[ref self: Self]` parameter if needed.
if (args.self_type_id.has_value()) {
context.full_pattern_stack().PushFullPattern(
FullPatternStack::Kind::ImplicitParamList);
context.full_pattern_stack().StartImplicitParamList();
BeginSubpattern(context);
auto self_type_region_id = EndSubpatternAsExpr(
@@ -129,13 +135,11 @@ static auto MakeFunctionSignature(Context& context, SemIR::LocId loc_id,
context.inst_blocks().Add({insts.self_param_id});
context.full_pattern_stack().EndImplicitParamList();
} else {
context.full_pattern_stack().PushFullPattern(
FullPatternStack::Kind::ExplicitParamList);
}
// Build and add any explicit parameters. We always use value parameters for
// now.
context.full_pattern_stack().StartExplicitParamList();
if (args.param_type_ids.empty()) {
insts.param_patterns_id = SemIR::InstBlockId::Empty;
} else {
@@ -151,6 +155,7 @@ static auto MakeFunctionSignature(Context& context, SemIR::LocId loc_id,
}
insts.param_patterns_id = context.inst_block_stack().Pop();
}
context.full_pattern_stack().EndExplicitParamList();
// Build and add the return type. We always use an initializing form for now.
if (args.return_type_id.has_value()) {
@@ -168,7 +173,6 @@ static auto MakeFunctionSignature(Context& context, SemIR::LocId loc_id,
insts.call_params_id = match_results.call_params_id;
insts.call_param_ranges = match_results.param_ranges;
context.full_pattern_stack().PopFullPattern();
auto [pattern_block_id, decl_block_id] =
FinishFunctionSignature(context, /*check_unused=*/false);
insts.pattern_block_id = pattern_block_id;
@@ -428,10 +432,12 @@ auto StartFunctionSignature(Context& context) -> void {
context.scope_stack().PushForDeclName();
context.inst_block_stack().Push();
context.pattern_block_stack().Push();
context.full_pattern_stack().PushParameterizedDecl();
}
auto FinishFunctionSignature(Context& context, bool check_unused)
-> FinishFunctionSignatureResult {
context.full_pattern_stack().PopFullPattern();
auto pattern_block_id = context.pattern_block_stack().Pop();
auto decl_block_id = context.inst_block_stack().Pop();
context.scope_stack().Pop(check_unused);