-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Preserve Opaque Types when evaluating ReactDRO destructor
Summary: The ReactDRO destructor adds a flag to all object types that make that object deeply-read-only for local analysis. This is unique among destructors in that it isn't really *transforming* the type as it is *marking* the type. Typically, we handle OpaqueTs in destructors by using their underlying type or otherwise falling back on behavior in flow_js.ml's larger pattern match when the underlying type is not exposable. For destructors that transform this makes sense: there's no sense in keeping around an opaque type because the opaque type is undergoing a transformation that would make it fundamentally different than its original definition. There's no sense in making that type opaque. But for ReactDRO, we don't actually want to lose the opaque type, we just want to mark the underlying_t and super_t with the ReactDRO marker. It would make sense to preserve the opacity, and a DRO OpaqueT should be compatible with its non-DRO equivalent, since ReactDRO is just for local analysis. This diff solves the issue by preserving opacity when evaluating ReactDRO on an opaque type. We have to go one extra step of forcing the evaluation of ReactDRO applied to the underlying_t and super_t because our refinement machinery expects to be able to inspect the underlying_t and super_t of opaque types. Without the change to eagerly evaluate we get ~50 errors matching the conditional.js test case added. Changelog: [fix] Fixed a behavior where component syntax would transform opaque types into their underlying types. Reviewed By: SamChou19815 Differential Revision: D55575945 fbshipit-source-id: 64a6ca0febf717f6aa4e047e20a8a052f520abf1
- Loading branch information
1 parent
5af3be7
commit 9c45ed6
Showing
8 changed files
with
139 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
tests/opaque_types_and_component_syntax_destructors/.flowconfig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[options] | ||
component_syntax=true | ||
no_flowlib=false | ||
all=true |
7 changes: 7 additions & 0 deletions
7
tests/opaque_types_and_component_syntax_destructors/conditional.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
component Foo() { | ||
return null; | ||
} | ||
component Bar(x: React.Element<typeof Foo>) { | ||
const y: number = x && 3; // OK | ||
return null; | ||
} |
9 changes: 9 additions & 0 deletions
9
tests/opaque_types_and_component_syntax_destructors/non-local.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import {Context} from './opaque'; | ||
import {useContext} from 'react'; | ||
import * as React from 'react'; | ||
|
||
component Foo() { | ||
const context = useContext(Context); | ||
context as number; // ERROR | ||
return null; | ||
} |
11 changes: 11 additions & 0 deletions
11
tests/opaque_types_and_component_syntax_destructors/opaque.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import {createContext, useContext} from 'react' | ||
|
||
export opaque type Tag = number; | ||
|
||
export const Context: React$Context<Tag> = createContext<Tag>(3); | ||
|
||
component Foo() { | ||
const context = useContext(Context); | ||
context as number; // OK | ||
return null; | ||
} |
19 changes: 19 additions & 0 deletions
19
..._types_and_component_syntax_destructors/opaque_types_and_component_syntax_destructors.exp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Error ------------------------------------------------------------------------------------------------- non-local.js:7:3 | ||
|
||
Cannot cast `context` to number because `Tag` [1] is incompatible with number [2]. [incompatible-cast] | ||
|
||
non-local.js:7:3 | ||
7| context as number; // ERROR | ||
^^^^^^^ | ||
|
||
References: | ||
opaque.js:5:37 | ||
5| export const Context: React$Context<Tag> = createContext<Tag>(3); | ||
^^^ [1] | ||
non-local.js:7:14 | ||
7| context as number; // ERROR | ||
^^^^^^ [2] | ||
|
||
|
||
|
||
Found 1 error |