Skip to content

Commit 89a46a5

Browse files
authored
[compiler][optim] more shapes for mixedreadonly (#32594)
- Add `at`, `indexOf`, and `includes` - Optimize MixedReadOnly which is currently only used by hook return values. Hook return values are typed as Frozen, this change propagates that to return values of aliasing function calls (such as `at`). One potential issue is that developers may pass `enableAssumeHooksFollowRulesOfReact:false` and set `transitiveMixedData`, expecting their transitive mixed data to be mutable. This is a bit of an edge case and already doesn't have clear semantics. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32594). * #32596 * #32595 * __->__ #32594 * #32593 * #32522 * #32521
1 parent eb53139 commit 89a46a5

File tree

1 file changed

+56
-2
lines changed

1 file changed

+56
-2
lines changed

compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts

+56-2
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,30 @@ addObject(BUILTIN_SHAPES, BuiltInRefValueId, [
535535
['*', {kind: 'Object', shapeId: BuiltInRefValueId}],
536536
]);
537537

538+
/**
539+
* MixedReadOnly =
540+
* | primitive
541+
* | simple objects (Record<string, MixedReadOnly>)
542+
* | Array<MixedReadOnly>
543+
*
544+
* APIs such as Relay — but also Flux and other data stores — often return a
545+
* union of types with some interesting properties in terms of analysis.
546+
*
547+
* Given this constraint, if data came from Relay, then we should be able to
548+
* infer things like `data.items.map(): Array`. That may seem like a leap at
549+
* first but remember, we assume you're not patching builtins. Thus the only way
550+
* data.items.map can exist and be a function, given the above set of data types
551+
* and builtin JS methods, is if `data.items` was an Array, and `data.items.map`
552+
* is therefore calling Array.prototype.map. Then we know that function returns
553+
* an Array as well. This relies on the fact that map() is being called, so if
554+
* data.items was some other type it would error at runtime - so it's sound.
555+
*
556+
* Note that this shape is currently only used for hook return values, which
557+
* means that it's safe to type aliasing method-call return kinds as `Frozen`.
558+
*
559+
* Also note that all newly created arrays from method-calls (e.g. `.map`)
560+
* have the appropriate mutable `BuiltInArray` shape
561+
*/
538562
addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [
539563
[
540564
'toString',
@@ -546,6 +570,36 @@ addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [
546570
returnValueKind: ValueKind.Primitive,
547571
}),
548572
],
573+
[
574+
'indexOf',
575+
addFunction(BUILTIN_SHAPES, [], {
576+
positionalParams: [],
577+
restParam: Effect.Read,
578+
returnType: {kind: 'Primitive'},
579+
calleeEffect: Effect.Read,
580+
returnValueKind: ValueKind.Primitive,
581+
}),
582+
],
583+
[
584+
'includes',
585+
addFunction(BUILTIN_SHAPES, [], {
586+
positionalParams: [],
587+
restParam: Effect.Read,
588+
returnType: {kind: 'Primitive'},
589+
calleeEffect: Effect.Read,
590+
returnValueKind: ValueKind.Primitive,
591+
}),
592+
],
593+
[
594+
'at',
595+
addFunction(BUILTIN_SHAPES, [], {
596+
positionalParams: [Effect.Read],
597+
restParam: null,
598+
returnType: {kind: 'Object', shapeId: BuiltInMixedReadonlyId},
599+
calleeEffect: Effect.Capture,
600+
returnValueKind: ValueKind.Frozen,
601+
}),
602+
],
549603
[
550604
'map',
551605
addFunction(BUILTIN_SHAPES, [], {
@@ -642,9 +696,9 @@ addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [
642696
addFunction(BUILTIN_SHAPES, [], {
643697
positionalParams: [],
644698
restParam: Effect.ConditionallyMutate,
645-
returnType: {kind: 'Poly'},
699+
returnType: {kind: 'Object', shapeId: BuiltInMixedReadonlyId},
646700
calleeEffect: Effect.ConditionallyMutate,
647-
returnValueKind: ValueKind.Mutable,
701+
returnValueKind: ValueKind.Frozen,
648702
noAlias: true,
649703
mutableOnlyIfOperandsAreMutable: true,
650704
}),

0 commit comments

Comments
 (0)