diff --git a/src/typing/errors/flow_intermediate_error.ml b/src/typing/errors/flow_intermediate_error.ml index ae2d04fc911..194684fcc12 100644 --- a/src/typing/errors/flow_intermediate_error.ml +++ b/src/typing/errors/flow_intermediate_error.ml @@ -576,6 +576,14 @@ let rec make_intermediate_error : | Op (DeleteProperty { prop; lhs }) -> root loc frames lhs (RootCannotDelete (desc prop)) | Op (RefinementCheck { test; discriminant }) -> root loc frames test (RootCannotCheckAgainst { test = desc test; discriminant }) + | Op (SwitchRefinementCheck { test; discriminant }) -> + let root_loc = loc_of_aloc test in + root_with_loc_and_specific_loc + loc + frames + root_loc + root_loc + (RootCannotCheckAgainstSwitchDiscriminant discriminant) | Op (MatchingProp { op; obj; key; sentinel_reason }) -> root loc frames op (RootCannotCompareWithProperty { sentinel = sentinel_reason; obj; key }) | Op (EvalMappedType { mapped_type }) -> @@ -1263,6 +1271,11 @@ let to_printable_error : | RootCannotCast { lower; upper } -> [text "Cannot cast "; desc lower; text " to "; desc upper] | RootCannotCheckAgainst { test; discriminant } -> [text "Invalid check of "; desc test; text " against "; ref discriminant] + | RootCannotCheckAgainstSwitchDiscriminant discriminant_loc -> + [ + text "Invalid check of case test against "; + hardcoded_string_desc_ref "switch discriminant" discriminant_loc; + ] | RootCannotCoerce { from; target } -> [text "Cannot coerce "; desc from; text " to "; desc target] | RootCannotConformToCommonInterface -> [text "Cannot conform to common interface module"] diff --git a/src/typing/errors/flow_intermediate_error_types.ml b/src/typing/errors/flow_intermediate_error_types.ml index 2ec3d0e7890..63c15b5fce4 100644 --- a/src/typing/errors/flow_intermediate_error_types.ml +++ b/src/typing/errors/flow_intermediate_error_types.ml @@ -255,6 +255,7 @@ type 'loc root_message = test: 'loc virtual_reason_desc; discriminant: 'loc virtual_reason; } + | RootCannotCheckAgainstSwitchDiscriminant of 'loc | RootCannotCoerce of { from: 'loc virtual_reason_desc; target: 'loc virtual_reason_desc; diff --git a/src/typing/flow_js.ml b/src/typing/flow_js.ml index fc2c8d2807d..0e5b04838ba 100644 --- a/src/typing/flow_js.ml +++ b/src/typing/flow_js.ml @@ -120,9 +120,9 @@ let strict_equatable_error cond_context (l, r) = let comparison_error = lazy (match cond_context with - | Some (SwitchTest { case_test_reason; switch_discriminant_reason }) -> + | Some (SwitchTest { case_test_loc; switch_discriminant_loc }) -> let use_op = - Op (RefinementCheck { test = case_test_reason; discriminant = switch_discriminant_reason }) + Op (SwitchRefinementCheck { test = case_test_loc; discriminant = switch_discriminant_loc }) in Error_message.EIncompatibleWithUseOp { reason_lower = reason_of_t l; reason_upper = reason_of_t r; use_op } @@ -8976,6 +8976,7 @@ struct true | Cast _ | RefinementCheck _ + | SwitchRefinementCheck _ | ClassExtendsCheck _ | ClassMethodDefinition _ | ClassImplementsCheck _ diff --git a/src/typing/statement.ml b/src/typing/statement.ml index 81b31ea3cd9..bedeecbb84d 100644 --- a/src/typing/statement.ml +++ b/src/typing/statement.ml @@ -1130,14 +1130,13 @@ module Make } ) in - let case_test_reason = mk_reason (RCustom "case test") (fst expr) in - let switch_discriminant_reason = - mk_reason (RCustom "switch discriminant") (fst discriminant) - in let (_, fake_ast) = condition cx - ~cond:(SwitchTest { case_test_reason; switch_discriminant_reason }) + ~cond: + (SwitchTest + { case_test_loc = fst expr; switch_discriminant_loc = fst discriminant } + ) fake in let expr_ast = diff --git a/src/typing/type.ml b/src/typing/type.ml index 1a27e89ba6e..9439b6dd21b 100644 --- a/src/typing/type.ml +++ b/src/typing/type.ml @@ -432,6 +432,10 @@ module rec TypeTerm : sig test: 'loc virtual_reason; discriminant: 'loc virtual_reason; } + | SwitchRefinementCheck of { + test: 'loc; + discriminant: 'loc; + } | MatchingProp of { op: 'loc virtual_reason; obj: 'loc virtual_reason; @@ -1008,8 +1012,8 @@ module rec TypeTerm : sig and cond_context = | SwitchTest of { - case_test_reason: reason; - switch_discriminant_reason: reason; + case_test_loc: ALoc.t; + switch_discriminant_loc: ALoc.t; } | OtherTest @@ -4142,6 +4146,7 @@ let string_of_root_use_op (type a) : a virtual_root_use_op -> string = function | SetProperty _ -> "SetProperty" | UpdateProperty _ -> "UpdateProperty" | RefinementCheck _ -> "RefinementCheck" + | SwitchRefinementCheck _ -> "SwitchRefinementCheck" | MatchingProp _ -> "MatchingProp" | EvalMappedType _ -> "EvalMappedType" | TypeGuardIncompatibility _ -> "TypeGuardIncompatibility" diff --git a/src/typing/typeUtil.ml b/src/typing/typeUtil.ml index 462018b7cb5..bafb439c7a4 100644 --- a/src/typing/typeUtil.ml +++ b/src/typing/typeUtil.ml @@ -455,6 +455,8 @@ let rec mod_loc_of_virtual_use_op f = UpdateProperty { lhs = mod_reason lhs; prop = mod_reason prop } | RefinementCheck { test; discriminant } -> RefinementCheck { test = mod_reason test; discriminant = mod_reason discriminant } + | SwitchRefinementCheck { test; discriminant } -> + SwitchRefinementCheck { test = f test; discriminant = f discriminant } | MatchingProp { op; obj; key; sentinel_reason } -> MatchingProp {