[compiler] Disambiguate between void, implicit, and explicit returns (#33989)
Adds a new property to ReturnTerminals to disambiguate whether it was explicit, implicit (arrow function expressions), or void (where it was omitted). I will use this property in the next PR adding a new validation pass. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33989). * #34022 * #34002 * #34001 * #33990 * __->__ #33989
lauren committed
Jul 28, 2025 at 12:46 UTC
5dd622eabe38e01781b3699d0d81c4a16e302f09
6 files changed
+19
-1
compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts
+3
@@ -189,6 +189,7 @@ export function lower(
189
const fallthrough = builder.reserve('block');
190
const terminal: ReturnTerminal = {
191
kind: 'return',
192
+ returnVariant: 'Implicit',
193
loc: GeneratedSource,
194
value: lowerExpressionToTemporary(builder, body),
195
id: makeInstructionId(0),
@@ -219,6 +220,7 @@ export function lower(
220
builder.terminate(
221
{
222
kind: 'return',
223
+ returnVariant: 'Void',
224
loc: GeneratedSource,
225
value: lowerValueToTemporary(builder, {
226
kind: 'Primitive',
@@ -302,6 +304,7 @@ function lowerStatement(
304
}
305
const terminal: ReturnTerminal = {
306
kind: 'return',
307
+ returnVariant: 'Explicit',
308
loc: stmt.node.loc ?? GeneratedSource,
309
value,
310
id: makeInstructionId(0),
compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
+12
@@ -446,8 +446,20 @@ export type ThrowTerminal = {
446
};
447
export type Case = {test: Place | null; block: BlockId};
448
449
+export type ReturnVariant = 'Void' | 'Implicit' | 'Explicit';
450
export type ReturnTerminal = {
451
kind: 'return';
452
+ /**
453
+ * Void:
454
+ * () => { ... }
455
+ * function() { ... }
456
+ * Implicit (ArrowFunctionExpression only):
457
+ * () => foo
458
+ * Explicit:
459
+ * () => { return ... }
460
+ * function () { return ... }
461
+ */
462
+ returnVariant: ReturnVariant;
463
loc: SourceLocation;
464
value: Place;
465
id: InstructionId;
compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts
+1
-1
@@ -215,7 +215,7 @@ export function printTerminal(terminal: Terminal): Array<string> | string {
215
break;
216
}
217
case 'return': {
218
- value = `[${terminal.id}] Return${
218
+ value = `[${terminal.id}] Return ${terminal.returnVariant}${
219
terminal.value != null ? ' ' + printPlace(terminal.value) : ''
220
}`;
221
if (terminal.effects != null) {
compiler/packages/babel-plugin-react-compiler/src/HIR/visitors.ts
+1
@@ -777,6 +777,7 @@ export function mapTerminalSuccessors(
777
case 'return': {
778
return {
779
kind: 'return',
780
+ returnVariant: terminal.returnVariant,
781
loc: terminal.loc,
782
value: terminal.value,
783
id: makeInstructionId(0),
compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts
+1
@@ -237,6 +237,7 @@ function emitSelectorFn(env: Environment, keys: Array<string>): Instruction {
237
terminal: {
238
id: makeInstructionId(0),
239
kind: 'return',
240
+ returnVariant: 'Explicit',
241
loc: GeneratedSource,
242
value: arrayInstr.lvalue,
243
effects: null,
compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts
+1
@@ -352,6 +352,7 @@ function emitOutlinedFn(
352
terminal: {
353
id: makeInstructionId(0),
354
kind: 'return',
355
+ returnVariant: 'Explicit',
356
loc: GeneratedSource,
357
value: instructions.at(-1)!.lvalue,
358
effects: null,