From e84f7c7300039a7cd815bba70e1e16f35b8b078b Mon Sep 17 00:00:00 2001 From: Sam Zhou Date: Fri, 6 Dec 2024 21:23:10 -0800 Subject: [PATCH] [flow][multiplat] Support nominal renders in common interface files Summary: Followup of D66711903. We need to do this for render as well. Unlike the component subtyping case, we do not need to do a component structural subtyping checking here, since the same check would already be done during the common interface conformance check Changelog: [internal] Reviewed By: gkz Differential Revision: D66887907 fbshipit-source-id: fc7a59e25060e531bfb92015b8335f2bd42aa479 --- src/typing/renders_kit.ml | 14 ++++++++--- .../multiplatform_subtyping/component.ios.js | 6 ++++- .../multiplatform_subtyping/component.js.flow | 5 +++- .../multiplatform_subtyping.exp | 24 +++++++++++++++---- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/typing/renders_kit.ml b/src/typing/renders_kit.ml index 7e53bb8ec40..01efb2402fc 100644 --- a/src/typing/renders_kit.ml +++ b/src/typing/renders_kit.ml @@ -83,10 +83,18 @@ module Make (Flow : INPUT) : S = struct explanation = None; } ) - | ( NominalRenders { renders_id = id1; renders_name = _; renders_super }, - NominalRenders { renders_id = id2; renders_name = _; renders_super = _ } + | ( NominalRenders { renders_id = id1; renders_name = name_1; renders_super }, + NominalRenders { renders_id = id2; renders_name = name_2; renders_super = _ } ) -> - if ALoc.equal_id id1 id2 then + if + ALoc.equal_id id1 id2 + || + let file_options = Context.((metadata cx).file_options) in + TypeUtil.nominal_id_have_same_logical_module + ~file_options + (id1, Some name_1) + (id2, Some name_2) + then () else (* We reposition the super using l's reason for better error messages *) diff --git a/tests/multiplatform_subtyping/component.ios.js b/tests/multiplatform_subtyping/component.ios.js index ab34364d55c..7d7705b051c 100644 --- a/tests/multiplatform_subtyping/component.ios.js +++ b/tests/multiplatform_subtyping/component.ios.js @@ -1 +1,5 @@ -declare export component Foo(bar: string, baz: number); // incompatible-type with baz prop, otherwise ok +declare export component Foo(bar: string, baz: number) renders Base; // incompatible-type with baz prop, otherwise ok +declare component Base(); +declare component Acid(); + +declare export component DifferentRenders() renders Acid; // error: incompatible renders type diff --git a/tests/multiplatform_subtyping/component.js.flow b/tests/multiplatform_subtyping/component.js.flow index fa46e6a564b..3e2c7092013 100644 --- a/tests/multiplatform_subtyping/component.js.flow +++ b/tests/multiplatform_subtyping/component.js.flow @@ -1 +1,4 @@ -declare export component Foo(bar: string, baz: boolean) +declare export component Foo(bar: string, baz: boolean) renders Base; +declare component Base(); + +declare export component DifferentRenders() renders Base; diff --git a/tests/multiplatform_subtyping/multiplatform_subtyping.exp b/tests/multiplatform_subtyping/multiplatform_subtyping.exp index 9c2c4056ba0..86a951797cd 100644 --- a/tests/multiplatform_subtyping/multiplatform_subtyping.exp +++ b/tests/multiplatform_subtyping/multiplatform_subtyping.exp @@ -449,18 +449,34 @@ Read the docs on Flow's multi-platform support for more information: https://flo [incompatible-type] component.ios.js:1:26 - 1| declare export component Foo(bar: string, baz: number); // incompatible-type with baz prop, otherwise ok + 1| declare export component Foo(bar: string, baz: number) renders Base; // incompatible-type with baz prop, otherwise ok ^^^ References: component.js.flow:1:48 - 1| declare export component Foo(bar: string, baz: boolean) + 1| declare export component Foo(bar: string, baz: boolean) renders Base; ^^^^^^^ [1] component.ios.js:1:48 - 1| declare export component Foo(bar: string, baz: number); // incompatible-type with baz prop, otherwise ok + 1| declare export component Foo(bar: string, baz: number) renders Base; // incompatible-type with baz prop, otherwise ok ^^^^^^ [2] +Error -------------------------------------------------------------------------------------------- component.ios.js:5:45 + +Cannot conform to common interface module because `Acid` [1] does not render `Base` [2] in property `DifferentRenders`. +Read the docs on Flow's multi-platform support for more information: https://flow.org/en/docs/react/multiplatform. +[incompatible-type] + + component.ios.js:5:45 + 5| declare export component DifferentRenders() renders Acid; // error: incompatible renders type + ^^^^^^^^^^^^ [1] + +References: + component.js.flow:4:45 + 4| declare export component DifferentRenders() renders Base; + ^^^^^^^^^^^^ [2] + + Error ----------------------------------------------------------------------------------------------- enums.ios.js:11:21 Cannot conform to common interface module because `FooBad` [1] is incompatible with `FooBad` [2] in property `FooBad`. @@ -670,4 +686,4 @@ References: -Found 37 errors +Found 38 errors