1 // Copyright (c) Meta Platforms, Inc. and affiliates.
3 // This source code is licensed under the MIT license found in the
4 // LICENSE file in the "hack" directory of this source tree.
9 local_error::TypingError,
12 pub use constraint::Cstr;
13 use hcons::{Conser, Hc};
15 use oxidized::ast_defs::Variance;
19 /// TODO[mjt] Consider making 'constraints' 'types' to avoid this
20 /// or maybe rethink the inference env entirely
21 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
22 pub enum CstrTy<R: Reason> {
27 impl<R: Reason> CstrTy<R> {
28 pub fn tyvars<F>(&self, get_tparam_variance: &F) -> (HashSet<Tyvar>, HashSet<Tyvar>)
30 F: Fn(TypeName) -> Option<Vec<Variance>>,
33 CstrTy::Locl(ty) => ty.tyvars(get_tparam_variance),
34 CstrTy::Cstr(cstr) => cstr.tyvars(get_tparam_variance),
39 pub fn tyvar_opt(&self) -> Option<&Tyvar> {
41 Self::Locl(ty) => ty.tyvar_opt(),
42 Self::Cstr(_) => None,
46 pub fn is_var(&self) -> bool {
47 self.tyvar_opt().is_some()
51 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
52 pub enum PropF<R: Reason, A> {
54 Disj(TypingError<R>, Vec<A>),
55 Subtype(CstrTy<R>, CstrTy<R>),
58 impl<R: Reason> PropF<R, Prop<R>> {
59 pub fn inj(self) -> Prop<R> {
64 impl<R: Reason> hcons::Consable for PropF<R, Prop<R>> {
66 fn conser() -> &'static Conser<PropF<R, Prop<R>>> {
71 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
72 pub struct Prop<R: Reason>(Hc<PropF<R, Prop<R>>>);
74 impl<R: Reason> Deref for Prop<R> {
75 type Target = PropF<R, Prop<R>>;
76 fn deref(&self) -> &Self::Target {
77 let Prop(hc_prop_f) = self;
78 Deref::deref(hc_prop_f)
82 impl<R: Reason> Prop<R> {
83 pub fn conjs(ps: Vec<Prop<R>>) -> Self {
87 pub fn conj(self, other: Self) -> Self {
88 Self::conjs(vec![self, other])
91 pub fn disjs(ps: Vec<Prop<R>>, fail: TypingError<R>) -> Self {
92 PropF::Disj(fail, ps).inj()
95 pub fn disj(self, other: Self, fail: TypingError<R>) -> Self {
96 Self::disjs(vec![self, other], fail)
99 pub fn subtype(cty_sub: CstrTy<R>, cty_sup: CstrTy<R>) -> Self {
100 PropF::Subtype(cty_sub, cty_sup).inj()
103 pub fn subtype_ty(ty_sub: Ty<R>, ty_sup: Ty<R>) -> Self {
104 Self::subtype(CstrTy::Locl(ty_sub), CstrTy::Locl(ty_sup))
107 pub fn valid() -> Self {
108 PropF::Conj(vec![]).inj()
111 pub fn invalid(fail: TypingError<R>) -> Self {
112 PropF::Disj(fail, vec![]).inj()
115 pub fn is_valid(&self) -> bool {
117 PropF::Subtype(_, _) => false,
118 PropF::Conj(ps) => ps.iter().all(|p| p.is_valid()),
119 PropF::Disj(_, ps) => ps.iter().any(|p| p.is_valid()),
123 pub fn is_unsat(&self) -> bool {
125 PropF::Subtype(_, _) => false,
126 PropF::Conj(ps) => ps.iter().any(|p| p.is_unsat()),
127 PropF::Disj(_, ps) => ps.iter().all(|p| p.is_unsat()),