Add the form ID to FormParamPattern (#6928)

This enables some nice simplifications, and it's also a step toward a
broader restructuring of binding and parameter patterns.

Assisted-by: Gemini 3.1 Pro via Antigravity
This commit is contained in:
Geoff Romer
2026-03-20 01:08:38 +00:00
committed by GitHub
parent ce50f181f1
commit 8e5b358ec2
11 changed files with 65 additions and 88 deletions
+1 -11
View File
@@ -12,25 +12,15 @@
interface I {
let T:! type;
// CHECK:STDERR: fail_todo_form_thunk.carbon:[[@LINE+7]]:8: error: semantics TODO: `Support for cloning form bindings` [SemanticsTodo]
// CHECK:STDERR: fail_todo_form_thunk.carbon:[[@LINE+4]]:8: error: semantics TODO: `Support for cloning form bindings` [SemanticsTodo]
// CHECK:STDERR: fn F(x:? form(ref ()), y: T);
// CHECK:STDERR: ^
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_form_thunk.carbon:[[@LINE+3]]:8: error: value expression passed to reference parameter [ValueForRefParam]
// CHECK:STDERR: fn F(x:? form(ref ()), y: T);
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
fn F(x:? form(ref ()), y: T);
}
class C {
impl as I where .T = () {
// CHECK:STDERR: fail_todo_form_thunk.carbon:[[@LINE+7]]:10: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fn F(x:? form(ref ()), ());
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_todo_form_thunk.carbon:[[@LINE-8]]:3: note: while building thunk to match the signature of this function [ThunkSignature]
// CHECK:STDERR: fn F(x:? form(ref ()), y: T);
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
fn F(x:? form(ref ()), ());
}
}
+2 -8
View File
@@ -3367,11 +3367,9 @@ fn F() {
// CHECK:STDOUT: %empty_tuple.type.as.J2.impl.F.decl.loc23_40.2: %empty_tuple.type.as.J2.impl.F.type.56bdaf.2 = fn_decl @empty_tuple.type.as.J2.impl.F.loc23_40.2 [concrete = constants.%empty_tuple.type.as.J2.impl.F.7b8679.2] {
// CHECK:STDOUT: %self.patt: %pattern_type.cb1 = value_binding_pattern self [concrete]
// CHECK:STDOUT: %self.param_patt: %pattern_type.cb1 = value_param_pattern %self.patt [concrete]
// CHECK:STDOUT: %.param_patt: <error> = value_param_pattern <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: %empty_tuple.type = value_param call_param0
// CHECK:STDOUT: %self: %empty_tuple.type = value_binding self, %self.param
// CHECK:STDOUT: %.param: <error> = value_param call_param1
// CHECK:STDOUT: }
// CHECK:STDOUT: %J2.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant, %empty_tuple.type.as.J2.impl.F.decl.loc23_40.2), @empty_tuple.type.as.J2.impl [concrete]
// CHECK:STDOUT: %J2.impl_witness: <witness> = impl_witness %J2.impl_witness_table [concrete = constants.%J2.impl_witness.941]
@@ -3407,11 +3405,9 @@ fn F() {
// CHECK:STDOUT: %C2.as.J2.impl.F.decl.loc32_40.2: %C2.as.J2.impl.F.type.d2a210.2 = fn_decl @C2.as.J2.impl.F.loc32_40.2 [concrete = constants.%C2.as.J2.impl.F.720bb2.2] {
// CHECK:STDOUT: %self.patt: %pattern_type.8df = value_binding_pattern self [concrete]
// CHECK:STDOUT: %self.param_patt: %pattern_type.8df = value_param_pattern %self.patt [concrete]
// CHECK:STDOUT: %.param_patt: <error> = value_param_pattern <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: %C2 = value_param call_param0
// CHECK:STDOUT: %self: %C2 = value_binding self, %self.param
// CHECK:STDOUT: %.param: <error> = value_param call_param1
// CHECK:STDOUT: }
// CHECK:STDOUT: %J2.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant, %C2.as.J2.impl.F.decl.loc32_40.2), @C2.as.J2.impl [concrete]
// CHECK:STDOUT: %J2.impl_witness: <witness> = impl_witness %J2.impl_witness_table [concrete = constants.%J2.impl_witness.30f]
@@ -3450,11 +3446,10 @@ fn F() {
// CHECK:STDOUT: return %.loc23_50
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @empty_tuple.type.as.J2.impl.F.loc23_40.2(%self.param: %empty_tuple.type, %.param: <error>) -> <error> [thunk @empty_tuple.type.as.J2.impl.%empty_tuple.type.as.J2.impl.F.decl.loc23_40.1] {
// CHECK:STDOUT: fn @empty_tuple.type.as.J2.impl.F.loc23_40.2(%self.param: %empty_tuple.type) -> <error> [thunk @empty_tuple.type.as.J2.impl.%empty_tuple.type.as.J2.impl.F.decl.loc23_40.1] {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %empty_tuple.type.as.J2.impl.F.type.56bdaf.1 = name_ref F, @empty_tuple.type.as.J2.impl.%empty_tuple.type.as.J2.impl.F.decl.loc23_40.1 [concrete = constants.%empty_tuple.type.as.J2.impl.F.7b8679.1]
// CHECK:STDOUT: %self.ref: %empty_tuple.type = name_ref self, %self.param
// CHECK:STDOUT: %.ref: <error> = name_ref <none>, %.param
// CHECK:STDOUT: %empty_tuple.type.as.J2.impl.F.bound: <bound method> = bound_method %self.ref, %F.ref
// CHECK:STDOUT: %empty_tuple.type.as.J2.impl.F.call: init %empty_struct_type = call %empty_tuple.type.as.J2.impl.F.bound(%self.ref, <error>)
// CHECK:STDOUT: return <error>
@@ -3470,11 +3465,10 @@ fn F() {
// CHECK:STDOUT: return %.loc32_53.4
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @C2.as.J2.impl.F.loc32_40.2(%self.param: %C2, %.param: <error>) -> <error> [thunk @C2.as.J2.impl.%C2.as.J2.impl.F.decl.loc32_40.1] {
// CHECK:STDOUT: fn @C2.as.J2.impl.F.loc32_40.2(%self.param: %C2) -> <error> [thunk @C2.as.J2.impl.%C2.as.J2.impl.F.decl.loc32_40.1] {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %C2.as.J2.impl.F.type.d2a210.1 = name_ref F, @C2.as.J2.impl.%C2.as.J2.impl.F.decl.loc32_40.1 [concrete = constants.%C2.as.J2.impl.F.720bb2.1]
// CHECK:STDOUT: %self.ref: %C2 = name_ref self, %self.param
// CHECK:STDOUT: %.ref: <error> = name_ref <none>, %.param
// CHECK:STDOUT: %C2.as.J2.impl.F.bound: <bound method> = bound_method %self.ref, %F.ref
// CHECK:STDOUT: %C2.as.J2.impl.F.call: init %C2 = call %C2.as.J2.impl.F.bound(%self.ref, <error>)
// CHECK:STDOUT: return <error>