You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.8 KiB

(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
module F = Format
type t =
| Null
| Nullable
| ThirdPartyNonnull
| UncheckedNonnull
| LocallyTrustedNonnull
| LocallyCheckedNonnull
| ProvisionallyNullable
| StrictNonnull
[@@deriving compare, equal]
type pair = t * t [@@deriving compare, equal]
let top = Nullable
let join x y =
match (x, y) with
| Null, Null ->
Null
| Null, _ | _, Null ->
Nullable
| Nullable, _ | _, Nullable ->
Nullable
| ThirdPartyNonnull, _ | _, ThirdPartyNonnull ->
ThirdPartyNonnull
| ProvisionallyNullable, _ | _, ProvisionallyNullable ->
ProvisionallyNullable
| UncheckedNonnull, _ | _, UncheckedNonnull ->
UncheckedNonnull
| LocallyTrustedNonnull, _ | _, LocallyTrustedNonnull ->
LocallyTrustedNonnull
| LocallyCheckedNonnull, _ | _, LocallyCheckedNonnull ->
LocallyCheckedNonnull
| StrictNonnull, StrictNonnull ->
StrictNonnull
let is_subtype ~subtype ~supertype = equal (join subtype supertype) supertype
let is_considered_nonnull ~nullsafe_mode nullability =
if equal ProvisionallyNullable nullability then
(* Deliberately ignoring modes for this type
(ProvisionallyNullable is currently not indented to work well with all features for non-default modes) *)
true
else
let least_required =
match nullsafe_mode with
| NullsafeMode.Strict ->
StrictNonnull
| NullsafeMode.Local (NullsafeMode.Trust.Only trust_list)
when NullsafeMode.Trust.is_trust_none trust_list ->
(* Though "trust none" is technically a subcase of trust some,
we need this pattern to be different from the one below so we can detect possible
promotions from "trust some" to "trust none" *)
LocallyCheckedNonnull
| NullsafeMode.Local (NullsafeMode.Trust.Only _) ->
LocallyTrustedNonnull
| NullsafeMode.Local NullsafeMode.Trust.All ->
UncheckedNonnull
| NullsafeMode.Default ->
(* In default mode, we trust everything, even not annotated third party. *)
ThirdPartyNonnull
in
is_subtype ~subtype:nullability ~supertype:least_required
let is_nonnullish t = is_considered_nonnull ~nullsafe_mode:NullsafeMode.Default t
let to_string = function
| Null ->
"Null"
| Nullable ->
"Nullable"
| ProvisionallyNullable ->
"ProvisionallyNullable"
| ThirdPartyNonnull ->
"ThirdPartyNonnull"
| UncheckedNonnull ->
"UncheckedNonnull"
| LocallyTrustedNonnull ->
"LocallyTrustedNonnull"
| LocallyCheckedNonnull ->
"LocallyCheckedNonnull"
| StrictNonnull ->
"StrictNonnull"
let pp fmt t = F.fprintf fmt "%s" (to_string t)