Skip to content

Commit 370a671

Browse files
SamChou19815meta-codesync[bot]
authored andcommitted
[flow][refactor] Restore readability of dispatch.rs and subtyping_kit.rs 14/n: enums and final pattern cleanup
Summary: Move enum object and value shapes into the subtyping match patterns, retaining guards for enum metadata. Reuse the concrete enum bindings when checking representation compatibility. Preserve the separate object/object and value/value alternatives. Combine the generic indexed-access helper's nested destructuring and tidy deep pattern layouts. Changelog: [internal] Simplify enum subtyping and the remaining indexed-access patterns. ___ landed-with-radar-review Differential Revision: D126949179 fbshipit-source-id: 682cf0af208c696cdeabe1c90d48502ab6e08913
1 parent ad74438 commit 370a671

2 files changed

Lines changed: 88 additions & 161 deletions

File tree

‎rust_port/crates/flow_typing_flow_js/src/flow_js/dispatch.rs‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -403,14 +403,17 @@ fn same_generic_indexed_access<'cx>(
403403
(t1, d1): (&Type, &TypeDestructorT),
404404
(t2, d2): (&Type, &TypeDestructorT),
405405
) -> bool {
406-
let (Destructor::ElementType { index_type: i1 }, Destructor::ElementType { index_type: i2 }) =
407-
(d1.2.as_ref(), d2.2.as_ref())
406+
let (
407+
Destructor::ElementType {
408+
index_type: deref!(GenericT(g1)),
409+
},
410+
Destructor::ElementType {
411+
index_type: deref!(GenericT(g2)),
412+
},
413+
) = (d1.2.as_ref(), d2.2.as_ref())
408414
else {
409415
return false;
410416
};
411-
let (GenericT(g1), GenericT(g2)) = (i1.deref(), i2.deref()) else {
412-
return false;
413-
};
414417
g1.id == g2.id && flow_js_utils::is_same_non_generic_instance_annot(cx, t1, t2)
415418
}
416419

‎rust_port/crates/flow_typing_flow_js/src/subtyping_kit.rs‎

Lines changed: 80 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,14 +1175,14 @@ fn try_method_bivariant<'cx>(
11751175
#[rustfmt::skip]
11761176
(
11771177
DefT(_, deref!(PolyT(box PolyTData {
1178-
tparams: ps1,
1179-
t_out: inner1 @ deref!(DefT(_, deref!(FunT(_, _)))),
1180-
..
1178+
tparams: ps1,
1179+
t_out: inner1 @ deref!(DefT(_, deref!(FunT(_, _)))),
1180+
..
11811181
}))),
11821182
DefT(_, deref!(PolyT(box PolyTData {
1183-
tparams: ps2,
1184-
t_out: inner2 @ deref!(DefT(_, deref!(FunT(_, _)))),
1185-
..
1183+
tparams: ps2,
1184+
t_out: inner2 @ deref!(DefT(_, deref!(FunT(_, _)))),
1185+
..
11861186
}))),
11871187
) if ps1.len() == ps2.len() => {
11881188
let (map1, generics) = flow_js_utils::mk_tparams(cx, ps1);
@@ -1309,18 +1309,16 @@ fn try_method_bivariant<'cx>(
13091309
#[rustfmt::skip]
13101310
(
13111311
DefT(_, deref!(PolyT(box PolyTData {
1312-
tparams: ps1,
1313-
t_out: deref!(DefT(_, deref!(FunT(_, _)))),
1314-
..
1312+
tparams: ps1,
1313+
t_out: deref!(DefT(_, deref!(FunT(_, _)))),
1314+
..
13151315
}))),
13161316
DefT(_, deref!(PolyT(box PolyTData {
1317-
tparams: ps2,
1318-
t_out: deref!(DefT(_, deref!(FunT(_, _)))),
1319-
..
1317+
tparams: ps2,
1318+
t_out: deref!(DefT(_, deref!(FunT(_, _)))),
1319+
..
13201320
}))),
1321-
) if ps1.len() == ps2.len() => {
1322-
true
1323-
},
1321+
) if ps1.len() == ps2.len() => true,
13241322
_ => false,
13251323
}
13261324
}
@@ -5106,9 +5104,9 @@ pub fn rec_sub_t<'cx>(
51065104
component_kind,
51075105
}))),
51085106
DefT(_, deref!(ReactAbstractComponentT(box ReactAbstractComponentTData {
5109-
config: configu,
5110-
renders: rendersu,
5111-
component_kind: ComponentKind::Structural,
5107+
config: configu,
5108+
renders: rendersu,
5109+
component_kind: ComponentKind::Structural,
51125110
}))),
51135111
) => {
51145112
FlowJs::rec_flow_t_with_env(cx, env, trace, use_op.dupe(), configu, configl)?;
@@ -5146,19 +5144,17 @@ pub fn rec_sub_t<'cx>(
51465144
..
51475145
}))),
51485146
DefT(_, deref!(ReactAbstractComponentT(box ReactAbstractComponentTData {
5149-
component_kind: ComponentKind::Nominal(idu, name_u, _),
5150-
config: configu,
5151-
renders: rendersu,
5152-
..
5147+
component_kind: ComponentKind::Nominal(idu, name_u, _),
5148+
config: configu,
5149+
renders: rendersu,
5150+
..
51535151
}))),
5154-
) if (idl == idu
5155-
|| type_util::nominal_id_have_same_logical_module(
5156-
&cx.file_options(),
5157-
cx.projects_options(),
5158-
(idl, Some(name_l.as_str())),
5159-
(idu, Some(name_u.as_str())),
5160-
)) =>
5161-
{
5152+
) if idl == idu || type_util::nominal_id_have_same_logical_module(
5153+
&cx.file_options(),
5154+
cx.projects_options(),
5155+
(idl, Some(name_l.as_str())),
5156+
(idu, Some(name_u.as_str())),
5157+
) => {
51625158
FlowJs::rec_flow_t_with_env(cx, env, trace, use_op.dupe(), configu, configl)?;
51635159
let use_op = UseOp::Frame(
51645160
Arc::new(VirtualFrameUseOp::RendersCompatibility),
@@ -5560,9 +5556,8 @@ pub fn rec_sub_t<'cx>(
55605556
// object is a subtype. We use `ExtendsUseT` to walk the proto chain of the
55615557
// object, in case it includes a nominal type.
55625558
(DefT(_, ld @ deref!(ObjT(_) | ClassT(_))), DefT(_, deref!(InstanceT(inst))))
5563-
if (matches!(ld.deref(), ObjT(_))
5564-
|| (matches!(ld.deref(), ClassT(_))
5565-
&& matches!(inst.inst.inst_kind, InstanceKind::ClassKind))) =>
5559+
if matches!(ld.deref(), ObjT(_))
5560+
|| matches!(inst.inst.inst_kind, InstanceKind::ClassKind) =>
55665561
{
55675562
FlowJs::rec_flow_with_env(
55685563
cx, env,
@@ -6255,13 +6250,10 @@ pub fn rec_sub_t<'cx>(
62556250
| UniqueSymbolT(_)
62566251
)),
62576252
DefT(_, ud @ deref!(InstanceT(_) | ObjT(_))),
6258-
) if (matches!(
6259-
ud.deref(),
6260-
InstanceT(inst)
6261-
if matches!(inst.inst.inst_kind, InstanceKind::InterfaceKind { reject_primitives: false, .. })
6262-
&& inst.inst.strictness_kind.is_typescript_loose()
6263-
) || matches!(ud.deref(), ObjT(obj) if obj.strictness_kind.is_typescript_loose())) =>
6264-
{
6253+
) if matches!(ud.deref(), InstanceT(inst)
6254+
if matches!(inst.inst.inst_kind, InstanceKind::InterfaceKind { reject_primitives: false, .. })
6255+
&& inst.inst.strictness_kind.is_typescript_loose()
6256+
) || matches!(ud.deref(), ObjT(obj) if obj.strictness_kind.is_typescript_loose()) => {
62656257
let builtin_name = match l.deref() {
62666258
DefT(_, deref!(BoolGeneralT | SingletonBoolT { .. })) => {
62676259
"Boolean"
@@ -6541,51 +6533,36 @@ pub fn rec_sub_t<'cx>(
65416533
// *********
65426534
// Enums
65436535
// *********
6544-
(DefT(_, ld), DefT(_, ud))
6545-
if matches!((ld.deref(), ud.deref()), (
6546-
EnumObjectT { enum_info: ei1, .. },
6547-
EnumObjectT { enum_info: ei2, .. },
6548-
) if matches!((ei1.deref().deref(), ei2.deref().deref()), (
6536+
(
6537+
DefT(_, deref!(EnumObjectT { enum_info: ei1, .. })),
6538+
DefT(_, deref!(EnumObjectT { enum_info: ei2, .. })),
6539+
) if let (
65496540
EnumInfoInner::ConcreteEnum(c1),
65506541
EnumInfoInner::ConcreteEnum(c2),
6551-
) if c1.enum_id == c2.enum_id)) =>
6542+
) = (ei1.deref().deref(), ei2.deref().deref())
6543+
&& c1.enum_id == c2.enum_id =>
65526544
{
65536545
Ok(())
65546546
}
6555-
(DefT(_, ld), DefT(_, ud))
6556-
if matches!((ld.deref(), ud.deref()), (
6557-
EnumValueT(ei1),
6558-
EnumValueT(ei2),
6559-
) if matches!((ei1.deref().deref(), ei2.deref().deref()), (
6547+
(DefT(_, deref!(EnumValueT(ei1))), DefT(_, deref!(EnumValueT(ei2))))
6548+
if let (
65606549
EnumInfoInner::ConcreteEnum(c1),
65616550
EnumInfoInner::ConcreteEnum(c2),
6562-
) if c1.enum_id == c2.enum_id)) =>
6551+
) = (ei1.deref().deref(), ei2.deref().deref())
6552+
&& c1.enum_id == c2.enum_id =>
65636553
{
65646554
Ok(())
65656555
}
6566-
(DefT(enum_reason_l, ld), DefT(enum_reason_u, ud))
6567-
if let Some((c1, c2)) = {
6568-
match (ld.deref(), ud.deref()) {
6569-
(
6570-
EnumObjectT { enum_info: ei1, .. },
6571-
EnumObjectT { enum_info: ei2, .. },
6572-
) => match (ei1.deref().deref(), ei2.deref().deref()) {
6573-
(EnumInfoInner::ConcreteEnum(c1), EnumInfoInner::ConcreteEnum(c2)) => {
6574-
Some((c1, c2))
6575-
}
6576-
_ => None,
6577-
},
6578-
(EnumValueT(ei1), EnumValueT(ei2)) => {
6579-
match (ei1.deref().deref(), ei2.deref().deref()) {
6580-
(EnumInfoInner::ConcreteEnum(c1), EnumInfoInner::ConcreteEnum(c2)) => {
6581-
Some((c1, c2))
6582-
}
6583-
_ => None,
6584-
}
6585-
}
6586-
_ => None,
6587-
}
6588-
} && type_util::nominal_id_have_same_logical_module(
6556+
(
6557+
DefT(enum_reason_l, deref!(EnumObjectT { enum_info: ei1, .. })),
6558+
DefT(enum_reason_u, deref!(EnumObjectT { enum_info: ei2, .. })),
6559+
)
6560+
| (
6561+
DefT(enum_reason_l, deref!(EnumValueT(ei1))),
6562+
DefT(enum_reason_u, deref!(EnumValueT(ei2))),
6563+
) if let (EnumInfoInner::ConcreteEnum(c1), EnumInfoInner::ConcreteEnum(c2)) =
6564+
(ei1.deref().deref(), ei2.deref().deref())
6565+
&& type_util::nominal_id_have_same_logical_module(
65896566
&cx.file_options(),
65906567
cx.projects_options(),
65916568
(&c1.enum_id, Some(c1.enum_name.as_str())),
@@ -6595,56 +6572,28 @@ pub fn rec_sub_t<'cx>(
65956572
&& c1.has_unknown_members == c2.has_unknown_members =>
65966573
{
65976574
if type_util::is_in_common_interface_conformance_check(&use_op) {
6598-
let repr_pair = match (ld.deref(), ud.deref()) {
6599-
(
6600-
EnumObjectT { enum_info: ei1, .. },
6601-
EnumObjectT { enum_info: ei2, .. },
6602-
) => match (ei1.deref().deref(), ei2.deref().deref()) {
6603-
(EnumInfoInner::ConcreteEnum(c1), EnumInfoInner::ConcreteEnum(c2)) => {
6604-
Some((&c1.representation_t, &c2.representation_t))
6605-
}
6606-
_ => None,
6607-
},
6608-
(EnumValueT(ei1), EnumValueT(ei2)) => {
6609-
match (ei1.deref().deref(), ei2.deref().deref()) {
6610-
(EnumInfoInner::ConcreteEnum(c1), EnumInfoInner::ConcreteEnum(c2)) => {
6611-
Some((&c1.representation_t, &c2.representation_t))
6612-
}
6613-
_ => None,
6614-
}
6615-
}
6616-
_ => None,
6617-
};
6618-
if let Some((r1, r2)) = repr_pair {
6619-
let use_op = VirtualUseOp::Frame(
6620-
Arc::new(VirtualFrameUseOp::EnumRepresentationTypeCompatibility {
6621-
lower: enum_reason_l.dupe(),
6622-
upper: enum_reason_u.dupe(),
6623-
}),
6624-
Arc::new(use_op),
6625-
);
6626-
FlowJs::rec_flow_t_with_env(cx, env, trace, use_op, r1, r2)?;
6627-
}
6575+
let use_op = VirtualUseOp::Frame(
6576+
Arc::new(VirtualFrameUseOp::EnumRepresentationTypeCompatibility {
6577+
lower: enum_reason_l.dupe(),
6578+
upper: enum_reason_u.dupe(),
6579+
}),
6580+
Arc::new(use_op),
6581+
);
6582+
FlowJs::rec_flow_t_with_env(
6583+
cx, env, trace, use_op, &c1.representation_t, &c2.representation_t,
6584+
)?;
66286585
}
66296586
Ok(())
66306587
}
66316588

6632-
(DefT(_, ld), DefT(_, ud))
6633-
if let (
6634-
EnumObjectT {
6635-
enum_value_t: ev1, ..
6636-
},
6637-
EnumObjectT {
6638-
enum_value_t: ev2, ..
6639-
},
6640-
) = (ld.deref(), ud.deref()) =>
6641-
{
6589+
(
6590+
DefT(_, deref!(EnumObjectT { enum_value_t: ev1, .. })),
6591+
DefT(_, deref!(EnumObjectT { enum_value_t: ev2, .. })),
6592+
) => {
66426593
FlowJs::rec_flow_t_with_env(cx, env, trace, use_op, ev1, ev2)
66436594
}
6644-
(DefT(enum_reason_l, ld), DefT(enum_reason_u, ud))
6645-
if let (EnumValueT(ei_l), EnumValueT(ei_u)) =
6646-
(ld.deref(), ud.deref())
6647-
&& let EnumInfoInner::AbstractEnum {
6595+
(DefT(enum_reason_l, deref!(EnumValueT(ei_l))), DefT(enum_reason_u, deref!(EnumValueT(ei_u))))
6596+
if let EnumInfoInner::AbstractEnum {
66486597
representation_t: repr_u,
66496598
} = ei_u.deref().deref() =>
66506599
{
@@ -6661,50 +6610,27 @@ pub fn rec_sub_t<'cx>(
66616610
);
66626611
FlowJs::rec_flow_t_with_env(cx, env, trace, use_op, repr_l, repr_u)
66636612
}
6664-
(DefT(enum_reason, ld), _)
6665-
if let EnumValueT(ei) = ld.deref()
6666-
&& let repr = match ei.deref().deref() {
6613+
(DefT(enum_reason, deref!(EnumValueT(ei))), _)
6614+
if let repr = match ei.deref().deref() {
66676615
EnumInfoInner::ConcreteEnum(c) => &c.representation_t,
66686616
EnumInfoInner::AbstractEnum { representation_t } => representation_t,
66696617
}
66706618
&& type_util::quick_subtype(None::<&mut fn(&Type)>, repr, u) =>
66716619
{
66726620
let representation_type = match repr.deref() {
6673-
DefT(_, d)
6674-
if matches!(
6675-
d.deref(),
6676-
BoolGeneralT | SingletonBoolT { .. }
6677-
) =>
6678-
{
6621+
DefT(_, deref!(BoolGeneralT | SingletonBoolT { .. })) => {
66796622
Some(FlowSmolStr::new_inline("boolean"))
66806623
}
6681-
DefT(_, d)
6682-
if matches!(
6683-
d.deref(),
6684-
NumGeneralT(_) | SingletonNumT { .. }
6685-
) =>
6686-
{
6624+
DefT(_, deref!(NumGeneralT(_) | SingletonNumT { .. })) => {
66876625
Some(FlowSmolStr::new_inline("number"))
66886626
}
6689-
DefT(_, d)
6690-
if matches!(
6691-
d.deref(),
6692-
StrGeneralT(_) | SingletonStrT { .. }
6693-
) =>
6694-
{
6627+
DefT(_, deref!(StrGeneralT(_) | SingletonStrT { .. })) => {
66956628
Some(FlowSmolStr::new_inline("string"))
66966629
}
6697-
DefT(_, d)
6698-
if matches!(d.deref(), SymbolT | UniqueSymbolT(_)) =>
6699-
{
6630+
DefT(_, deref!(SymbolT | UniqueSymbolT(_))) => {
67006631
Some(FlowSmolStr::new_inline("symbol"))
67016632
}
6702-
DefT(_, d)
6703-
if matches!(
6704-
d.deref(),
6705-
BigIntGeneralT(_) | SingletonBigIntT { .. }
6706-
) =>
6707-
{
6633+
DefT(_, deref!(BigIntGeneralT(_) | SingletonBigIntT { .. })) => {
67086634
Some(FlowSmolStr::new_inline("bigint"))
67096635
}
67106636
_ => None,
@@ -6713,13 +6639,11 @@ pub fn rec_sub_t<'cx>(
67136639
fn loop_(use_op: &UseOp) -> bool {
67146640
match use_op {
67156641
VirtualUseOp::Op(_) => false,
6716-
VirtualUseOp::Frame(frame, _)
6717-
if matches!(
6718-
frame.as_ref(),
6719-
VirtualFrameUseOp::TypeArgCompatibility(_)
6720-
| VirtualFrameUseOp::TypeParamBound { .. }
6721-
) =>
6722-
{
6642+
VirtualUseOp::Frame(
6643+
deref!(VirtualFrameUseOp::TypeArgCompatibility(_)
6644+
| VirtualFrameUseOp::TypeParamBound { .. }),
6645+
_,
6646+
) => {
67236647
true
67246648
}
67256649
VirtualUseOp::Frame(_, parent) => loop_(parent),

0 commit comments

Comments
 (0)