diff --git a/compiler/forget/src/HIR/BuildHIR.ts b/compiler/forget/src/HIR/BuildHIR.ts index ea74366b29..6ce95d612f 100644 --- a/compiler/forget/src/HIR/BuildHIR.ts +++ b/compiler/forget/src/HIR/BuildHIR.ts @@ -2113,32 +2113,6 @@ function lowerMemberExpression( const object = loweredObject ?? lowerExpressionToTemporary(builder, objectNode); - if ( - objectNode.isOptionalMemberExpression() && - !expr.isOptionalMemberExpression() - ) { - // Babel's `isOptionalMemberExpression` indicates whether this property load itself - // is conditional (i.e. within an "optional chain"). This is different from the - // `optional` property, which is only true for property loads at the start of an - // optional chain. e.g. `a.b?.c.d` decomposes into - // [0] MemberExpr a.b; // not in an optional chain - // [1] OptionalMemberExpr [0]?.c - // [2] OptionalMemberExpr [1].c - // [3] OptionalMemberExpr [2].d - // We currently do not handle non-conditional loads from an optional memberexpr - // e.g. `(a?.b).c` - // See error.nonoptional-load-from-optional-memberexpr test fixture for details - builder.errors.push({ - reason: `(BuildHIR::lowerMemberExpression) Handle optional chaining for non-optional member expr.`, - severity: ErrorSeverity.Todo, - nodePath: propertyNode, - }); - return { - object, - property: propertyNode.toString(), - value: { kind: "UnsupportedNode", node: exprNode, loc: exprLoc }, - }; - } if (!expr.node.computed) { if (!propertyNode.isIdentifier()) { builder.errors.push({ diff --git a/compiler/forget/src/__tests__/fixtures/compiler/error.nonoptional-load-from-optional-memberexpr.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/nonoptional-load-from-optional-memberexpr.expect.md similarity index 51% rename from compiler/forget/src/__tests__/fixtures/compiler/error.nonoptional-load-from-optional-memberexpr.expect.md rename to compiler/forget/src/__tests__/fixtures/compiler/nonoptional-load-from-optional-memberexpr.expect.md index 42ff978268..fea1945ab7 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/error.nonoptional-load-from-optional-memberexpr.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/nonoptional-load-from-optional-memberexpr.expect.md @@ -13,18 +13,17 @@ function Component(props) { ``` +## Code -## Error +```javascript +// Note that `a?.b.c` is semantically different from `(a?.b).c` +// Here, 'props?.a` is an optional chain, and `.b` is an unconditional load +// (nullthrows if a is nullish) + +function Component(props) { + const x = (props?.a).b; + return x; +} ``` -[ReactForget] TodoError: (BuildHIR::lowerMemberExpression) Handle optional chaining for non-optional member expr. - 4 | - 5 | function Component(props) { -> 6 | let x = (props?.a).b; - | ^ - 7 | return x; - 8 | } - 9 | -``` - \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/compiler/error.nonoptional-load-from-optional-memberexpr.js b/compiler/forget/src/__tests__/fixtures/compiler/nonoptional-load-from-optional-memberexpr.js similarity index 100% rename from compiler/forget/src/__tests__/fixtures/compiler/error.nonoptional-load-from-optional-memberexpr.js rename to compiler/forget/src/__tests__/fixtures/compiler/nonoptional-load-from-optional-memberexpr.js