mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Restructure return declaration handling (#7076)
- A function with a return declaration always has exactly one `ReturnSlotPattern`, representing the whole return declaration (whereas previously that was omitted for value and reference returns). - The `ReturnSlotPattern` always has a subpattern with the same form. `OutParamPattern` already plays that role for initializing forms, and `TuplePattern` will play that role for tuple forms. This change introduces `ValueReturnPattern` and `RefReturnPattern` to represent value and reference return forms. - As before, the `ReturnSlotPattern` has a corresponding `ReturnSlot` that represents the output that is initialized by a `return` statement. Its structure parallels the structure of the `ReturnSlotPattern`, so we need `ValueReturn` and `RefReturn` insts that correspond to `ValueReturnPattern` and `RefReturnPattern`. This is a step toward supporting generic return forms, where the `ReturnSlotPattern`'s subpattern may be an action: this change ensures that evaluating the action for a specific form produces the same SemIR as if the form were concrete to begin with. More speculatively, this should simplify the implementation of `return` statements with compound return forms. --------- Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This commit is contained in:
co-authored by
Chandler Carruth
parent
3abc334c42
commit
49c7288619
@@ -87,9 +87,12 @@ interface BeingDefined {
|
||||
// CHECK:STDOUT: %BeingDefined.WithSelf.decl = interface_with_self_decl @BeingDefined [concrete]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !with Self:
|
||||
// CHECK:STDOUT: %BeingDefined.WithSelf.H.decl: @BeingDefined.WithSelf.%BeingDefined.WithSelf.H.type (%BeingDefined.WithSelf.H.type) = fn_decl @BeingDefined.WithSelf.H [symbolic = @BeingDefined.WithSelf.%BeingDefined.WithSelf.H (constants.%BeingDefined.WithSelf.H)] {} {
|
||||
// CHECK:STDOUT: %BeingDefined.WithSelf.H.decl: @BeingDefined.WithSelf.%BeingDefined.WithSelf.H.type (%BeingDefined.WithSelf.H.type) = fn_decl @BeingDefined.WithSelf.H [symbolic = @BeingDefined.WithSelf.%BeingDefined.WithSelf.H (constants.%BeingDefined.WithSelf.H)] {
|
||||
// CHECK:STDOUT: %return.patt: <error> = return_slot_pattern <error>, <error> [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %BeingDefined.ref: type = name_ref BeingDefined, file.%BeingDefined.decl [concrete = constants.%BeingDefined.type]
|
||||
// CHECK:STDOUT: %T.ref: <error> = name_ref T, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %return: <error> = return_slot <error>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %assoc0: %BeingDefined.assoc_type = assoc_entity element0, %BeingDefined.WithSelf.H.decl [concrete = constants.%assoc0]
|
||||
// CHECK:STDOUT: %BeingDefined.WithSelf.I.decl: @BeingDefined.WithSelf.%BeingDefined.WithSelf.I.type (%BeingDefined.WithSelf.I.type) = fn_decl @BeingDefined.WithSelf.I [symbolic = @BeingDefined.WithSelf.%BeingDefined.WithSelf.I (constants.%BeingDefined.WithSelf.I)] {} {}
|
||||
|
||||
@@ -97,6 +97,7 @@ fn G(U:! Different) -> U.(Interface.T);
|
||||
// CHECK:STDOUT: %Different.decl: type = interface_decl @Different [concrete = constants.%Different.type] {} {}
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {
|
||||
// CHECK:STDOUT: %U.patt: %pattern_type.cb4 = symbolic_binding_pattern U, 0 [concrete]
|
||||
// CHECK:STDOUT: %return.patt: <error> = return_slot_pattern <error>, <error> [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %U.ref: %Different.type = name_ref U, %U.loc32_7.2 [symbolic = %U.loc32_7.1 (constants.%U)]
|
||||
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [concrete = constants.%Interface.type]
|
||||
@@ -107,6 +108,7 @@ fn G(U:! Different) -> U.(Interface.T);
|
||||
// CHECK:STDOUT: %Different.ref: type = name_ref Different, file.%Different.decl [concrete = constants.%Different.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %U.loc32_7.2: %Different.type = symbolic_binding U, 0 [symbolic = %U.loc32_7.1 (constants.%U)]
|
||||
// CHECK:STDOUT: %return: <error> = return_slot <error>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
Reference in New Issue
Block a user