From 8732aa92179840409f64da07eb7f3cfe59291322 Mon Sep 17 00:00:00 2001 From: Panos Vekris Date: Thu, 20 Feb 2025 21:58:10 -0800 Subject: [PATCH] [flow] handle singleton false in renders_kit Summary: Fill in some cases so that ``` declare const fls: false; (fls: renders* MenuItem); ``` is not an error. Changelog: [internal] Reviewed By: SamChou19815 Differential Revision: D69962310 fbshipit-source-id: cdf4c1fcc39a87a24897561fd6ab23ba1e1e208c --- src/typing/renders_kit.ml | 4 +-- tests/render_types/render_types.exp | 50 ++++++++++++++--------------- tests/render_types/renders_star.js | 1 + 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/typing/renders_kit.ml b/src/typing/renders_kit.ml index 14175c2e00a..fe977cdf56d 100644 --- a/src/typing/renders_kit.ml +++ b/src/typing/renders_kit.ml @@ -282,7 +282,7 @@ module Make (Flow : INPUT) : S = struct let non_renders_to_renders cx trace ~use_op l (renders_r, upper_renders) = match (l, upper_renders) with - | ( DefT (_, (NullT | VoidT | BoolT_UNSOUND false)), + | ( DefT (_, (NullT | VoidT | BoolT_UNSOUND false | SingletonBoolT false)), ( StructuralRenders { renders_variant = RendersMaybe | RendersStar; renders_structural_type = _ } | DefaultRenders ) @@ -405,7 +405,7 @@ module Make (Flow : INPUT) : S = struct FailedSynthesisState else on_concretized_react_node_types cx ~drop_renders_any ~state ts - | DefT (_, (NullT | VoidT | BoolT_UNSOUND false)) -> + | DefT (_, (NullT | VoidT | BoolT_UNSOUND false | SingletonBoolT false)) -> let renders_variant = merge_renders_variant (renders_variant, RendersMaybe) in IntermediateSynthesisState { normalized_render_type_collector; renders_variant } | DefT (_, ArrT (ArrayAT { elem_t = t; _ } | TupleAT { elem_t = t; _ } | ROArrayAT (t, _))) diff --git a/tests/render_types/render_types.exp b/tests/render_types/render_types.exp index a9c9435871d..e2429cfafb3 100644 --- a/tests/render_types/render_types.exp +++ b/tests/render_types/render_types.exp @@ -616,75 +616,75 @@ References: ^^^^ [3] -Error ---------------------------------------------------------------------------------------------- renders_star.js:8:2 +Error ---------------------------------------------------------------------------------------------- renders_star.js:9:2 Cannot cast `true` to renders* `MenuItem` because boolean [1] does not render `MenuItem` [2]. [incompatible-cast] - renders_star.js:8:2 - 8| (true: renders* MenuItem); // ERROR + renders_star.js:9:2 + 9| (true: renders* MenuItem); // ERROR ^^^^ [1] References: - renders_star.js:8:8 - 8| (true: renders* MenuItem); // ERROR + renders_star.js:9:8 + 9| (true: renders* MenuItem); // ERROR ^^^^^^^^^^^^^^^^^ [2] -Error -------------------------------------------------------------------------------------------- renders_star.js:20:58 +Error -------------------------------------------------------------------------------------------- renders_star.js:21:58 Cannot use read-only array type [1] as the type argument of renders type. Only elements of a component-syntax components can appear in renders. If you want to express the idea of rendering zero or more items, please use `renders*` instead. [invalid-render] - 20| declare const rendersChildrenArrayBlueMenuItem: renders? React.ChildrenArray; // invalid-render + 21| declare const rendersChildrenArrayBlueMenuItem: renders? React.ChildrenArray; // invalid-render ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [1] -Error -------------------------------------------------------------------------------------------- renders_star.js:24:30 +Error -------------------------------------------------------------------------------------------- renders_star.js:25:30 Cannot resolve name `RendersHuh`. [cannot-resolve-name] - 24| declare const rendersHuhBad: RendersHuh; + 25| declare const rendersHuhBad: RendersHuh; ^^^^^^^^^^ -Error -------------------------------------------------------------------------------------------- renders_star.js:28:32 +Error -------------------------------------------------------------------------------------------- renders_star.js:29:32 Cannot use boolean literal `false` [1], read-only array type [2], null [3] and undefined [4] as the type argument of renders type. Only elements of a component-syntax components can appear in renders. If you want to express the idea of rendering zero or more items, please use `renders*` instead. [invalid-render] - renders_star.js:28:32 - 28| (rendersStarMenuItem: renders (null | false | void | MenuItem | $ReadOnlyArray)); // type checks, but invalid-render + renders_star.js:29:32 + 29| (rendersStarMenuItem: renders (null | false | void | MenuItem | $ReadOnlyArray)); // type checks, but invalid-render ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ References: - renders_star.js:28:39 - 28| (rendersStarMenuItem: renders (null | false | void | MenuItem | $ReadOnlyArray)); // type checks, but invalid-render + renders_star.js:29:39 + 29| (rendersStarMenuItem: renders (null | false | void | MenuItem | $ReadOnlyArray)); // type checks, but invalid-render ^^^^^ [1] - renders_star.js:28:65 - 28| (rendersStarMenuItem: renders (null | false | void | MenuItem | $ReadOnlyArray)); // type checks, but invalid-render + renders_star.js:29:65 + 29| (rendersStarMenuItem: renders (null | false | void | MenuItem | $ReadOnlyArray)); // type checks, but invalid-render ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2] - renders_star.js:28:32 - 28| (rendersStarMenuItem: renders (null | false | void | MenuItem | $ReadOnlyArray)); // type checks, but invalid-render + renders_star.js:29:32 + 29| (rendersStarMenuItem: renders (null | false | void | MenuItem | $ReadOnlyArray)); // type checks, but invalid-render ^^^^ [3] - renders_star.js:28:47 - 28| (rendersStarMenuItem: renders (null | false | void | MenuItem | $ReadOnlyArray)); // type checks, but invalid-render + renders_star.js:29:47 + 29| (rendersStarMenuItem: renders (null | false | void | MenuItem | $ReadOnlyArray)); // type checks, but invalid-render ^^^^ [4] -Error -------------------------------------------------------------------------------------------- renders_star.js:30:35 +Error -------------------------------------------------------------------------------------------- renders_star.js:31:35 Cannot cast array literal to renders* `MenuItem` because `Bad` element [1] does not render `MenuItem` [2]. [incompatible-cast] - renders_star.js:30:35 - 30| ([, , ]: renders* MenuItem); // ERROR + renders_star.js:31:35 + 31| ([, , ]: renders* MenuItem); // ERROR ^^^^^^^ [1] References: - renders_star.js:30:45 - 30| ([, , ]: renders* MenuItem); // ERROR + renders_star.js:31:45 + 31| ([, , ]: renders* MenuItem); // ERROR ^^^^^^^^^^^^^^^^^ [2] diff --git a/tests/render_types/renders_star.js b/tests/render_types/renders_star.js index c9e5773f630..d0d129e92a0 100644 --- a/tests/render_types/renders_star.js +++ b/tests/render_types/renders_star.js @@ -2,6 +2,7 @@ import * as React from 'react'; component MenuItem() { return null } (null: renders* MenuItem); // OK (false: renders* MenuItem); // OK +(false as false: renders* MenuItem); // OK (undefined: renders* MenuItem); // OK ([null, [false, [undefined]]]: renders* MenuItem); // OK ([null, false, undefined]: renders* MenuItem); // OK