A newtype is a subtype of mixed
Summary:
Checking if a type is a subtype of `mixed = ?nonnull` is actually trickier than you think. Checking if the supertype matches `(_, Toption (_, Tnonnull))` is not enough because there may be other equivalent ways to express `mixed` that are syntactically different from `?nonnull`. E.g., `?T` where `T` is constrained using `super nonnull`.
To solve this issue for newtypes, we can treat an unconstrained newtype as one that has an implicit upper bound `?nonnull` (i.e., as if it was explicitly constrained using `as mixed`). Checking `N <: ?t_super` where `N` is a newtype defined as `newtype N as t_upper = t;` works by trying two choices: first we try to satisfy `N < t_super` and if that fails we try to satisfy `t_upper <: ?t_super`. By adding `?nonnull` as an implicit upper bound to a fully opaque newtype `N` when checking `N <: ?t_super`, we create a choice between `N <: t_super` and `?nonnull <: ?t_super` (equivalent to `nonnull <: t_super`). This allows us to type-check more code.
Reviewed By: andrewjkennedy
Differential Revision:
D9028981
fbshipit-source-id:
859763d3d43a4617885dc130f852c412514969d5