mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
fix: Type::has_type_satisfies
This commit is contained in:
parent
a876b34145
commit
1f51d188ea
4 changed files with 80 additions and 234 deletions
|
@ -537,48 +537,15 @@ impl SubrType {
|
|||
}
|
||||
|
||||
pub fn contains_tvar(&self, target: &FreeTyVar) -> bool {
|
||||
self.non_default_params
|
||||
.iter()
|
||||
.any(|pt| pt.typ().contains_tvar(target))
|
||||
|| self
|
||||
.var_params
|
||||
.as_ref()
|
||||
.map_or(false, |pt| pt.typ().contains_tvar(target))
|
||||
|| self.default_params.iter().any(|pt| {
|
||||
pt.typ().contains_tvar(target)
|
||||
|| pt.default_typ().is_some_and(|t| t.contains_tvar(target))
|
||||
})
|
||||
|| self.return_t.contains_tvar(target)
|
||||
self.has_type_satisfies(|t| t.contains_tvar(target))
|
||||
}
|
||||
|
||||
pub fn contains_type(&self, target: &Type) -> bool {
|
||||
self.non_default_params
|
||||
.iter()
|
||||
.any(|pt| pt.typ().contains_type(target))
|
||||
|| self
|
||||
.var_params
|
||||
.as_ref()
|
||||
.map_or(false, |pt| pt.typ().contains_type(target))
|
||||
|| self.default_params.iter().any(|pt| {
|
||||
pt.typ().contains_type(target)
|
||||
|| pt.default_typ().is_some_and(|t| t.contains_type(target))
|
||||
})
|
||||
|| self.return_t.contains_type(target)
|
||||
self.has_type_satisfies(|t| t.contains_type(target))
|
||||
}
|
||||
|
||||
pub fn contains_tp(&self, target: &TyParam) -> bool {
|
||||
self.non_default_params
|
||||
.iter()
|
||||
.any(|pt| pt.typ().contains_tp(target))
|
||||
|| self
|
||||
.var_params
|
||||
.as_ref()
|
||||
.map_or(false, |pt| pt.typ().contains_tp(target))
|
||||
|| self.default_params.iter().any(|pt| {
|
||||
pt.typ().contains_tp(target)
|
||||
|| pt.default_typ().is_some_and(|t| t.contains_tp(target))
|
||||
})
|
||||
|| self.return_t.contains_tp(target)
|
||||
self.has_type_satisfies(|t| t.contains_tp(target))
|
||||
}
|
||||
|
||||
pub fn map(self, f: &mut impl FnMut(Type) -> Type) -> Self {
|
||||
|
@ -708,48 +675,27 @@ impl SubrType {
|
|||
Set::multi_intersection(qnames_sets).extended(structural_qname)
|
||||
}
|
||||
|
||||
pub fn has_qvar(&self) -> bool {
|
||||
self.non_default_params.iter().any(|pt| pt.typ().has_qvar())
|
||||
|| self
|
||||
.var_params
|
||||
.as_ref()
|
||||
.map_or(false, |pt| pt.typ().has_qvar())
|
||||
pub fn has_type_satisfies(&self, f: impl Fn(&Type) -> bool + Copy) -> bool {
|
||||
self.non_default_params.iter().any(|pt| f(pt.typ()))
|
||||
|| self.var_params.as_ref().map_or(false, |pt| f(pt.typ()))
|
||||
|| self
|
||||
.default_params
|
||||
.iter()
|
||||
.any(|pt| pt.typ().has_qvar() || pt.default_typ().is_some_and(|t| t.has_qvar()))
|
||||
|| self.return_t.has_qvar()
|
||||
.any(|pt| f(pt.typ()) || pt.default_typ().is_some_and(f))
|
||||
|| self.kw_var_params.as_ref().map_or(false, |pt| f(pt.typ()))
|
||||
|| f(&self.return_t)
|
||||
}
|
||||
|
||||
pub fn has_qvar(&self) -> bool {
|
||||
self.has_type_satisfies(|t| t.has_qvar())
|
||||
}
|
||||
|
||||
pub fn has_unbound_var(&self) -> bool {
|
||||
self.non_default_params
|
||||
.iter()
|
||||
.any(|pt| pt.typ().has_unbound_var())
|
||||
|| self
|
||||
.var_params
|
||||
.as_ref()
|
||||
.map_or(false, |pt| pt.typ().has_unbound_var())
|
||||
|| self.default_params.iter().any(|pt| {
|
||||
pt.typ().has_unbound_var() || pt.default_typ().is_some_and(|t| t.has_unbound_var())
|
||||
})
|
||||
|| self.return_t.has_unbound_var()
|
||||
self.has_type_satisfies(|t| t.has_unbound_var())
|
||||
}
|
||||
|
||||
pub fn has_undoable_linked_var(&self) -> bool {
|
||||
self.non_default_params
|
||||
.iter()
|
||||
.any(|pt| pt.typ().has_undoable_linked_var())
|
||||
|| self
|
||||
.var_params
|
||||
.as_ref()
|
||||
.map_or(false, |pt| pt.typ().has_undoable_linked_var())
|
||||
|| self.default_params.iter().any(|pt| {
|
||||
pt.typ().has_undoable_linked_var()
|
||||
|| pt
|
||||
.default_typ()
|
||||
.is_some_and(|t| t.has_undoable_linked_var())
|
||||
})
|
||||
|| self.return_t.has_undoable_linked_var()
|
||||
self.has_type_satisfies(|t| t.has_undoable_linked_var())
|
||||
}
|
||||
|
||||
pub fn typarams(&self) -> Vec<TyParam> {
|
||||
|
@ -2953,91 +2899,37 @@ impl Type {
|
|||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
Self::Record(rec) => rec.iter().any(|(_, t)| t.contains_tvar(target)),
|
||||
Self::NamedTuple(rec) => rec.iter().any(|(_, t)| t.contains_tvar(target)),
|
||||
Self::Poly { params, .. } => params.iter().any(|tp| tp.contains_tvar(target)),
|
||||
Self::Quantified(t) => t.contains_tvar(target),
|
||||
Self::Subr(subr) => subr.contains_tvar(target),
|
||||
// TODO: preds
|
||||
Self::Refinement(refine) => refine.t.contains_tvar(target),
|
||||
Self::Structural(ty) => ty.contains_tvar(target),
|
||||
Self::Proj { lhs, .. } => lhs.contains_tvar(target),
|
||||
Self::ProjCall { lhs, args, .. } => {
|
||||
lhs.contains_tvar(target) || args.iter().any(|t| t.contains_tvar(target))
|
||||
}
|
||||
Self::And(tys) => tys.iter().any(|t| t.contains_tvar(target)),
|
||||
Self::Or(tys) => tys.iter().any(|t| t.contains_tvar(target)),
|
||||
Self::Not(t) => t.contains_tvar(target),
|
||||
Self::Ref(t) => t.contains_tvar(target),
|
||||
Self::RefMut { before, after } => {
|
||||
before.contains_tvar(target)
|
||||
|| after.as_ref().map_or(false, |t| t.contains_tvar(target))
|
||||
}
|
||||
Self::Bounded { sub, sup } => sub.contains_tvar(target) || sup.contains_tvar(target),
|
||||
Self::Callable { param_ts, return_t } => {
|
||||
param_ts.iter().any(|t| t.contains_tvar(target)) || return_t.contains_tvar(target)
|
||||
}
|
||||
Self::Guard(guard) => guard.to.contains_tvar(target),
|
||||
mono_type_pattern!() => false,
|
||||
_ => self.has_type_satisfies(|t| t.contains_tvar(target)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_type_satisfies(&self, f: impl Fn(&Type) -> bool + Copy) -> bool {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => fv.crack().has_type_satisfies(f),
|
||||
Self::FreeVar(fv) if fv.constraint_is_typeof() => {
|
||||
fv.get_type().unwrap().has_type_satisfies(f)
|
||||
}
|
||||
Self::FreeVar(fv) if fv.is_linked() => f(&fv.crack()),
|
||||
Self::FreeVar(fv) if fv.constraint_is_typeof() => f(&fv.get_type().unwrap()),
|
||||
Self::FreeVar(fv) => fv
|
||||
.get_subsup()
|
||||
.map(|(sub, sup)| {
|
||||
fv.do_avoiding_recursion(|| {
|
||||
sub.has_type_satisfies(f) || sup.has_type_satisfies(f)
|
||||
})
|
||||
})
|
||||
.map(|(sub, sup)| fv.do_avoiding_recursion(|| f(&sub) || f(&sup)))
|
||||
.unwrap_or(false),
|
||||
Self::Record(rec) => rec.iter().any(|(_, t)| t.has_type_satisfies(f)),
|
||||
Self::NamedTuple(rec) => rec.iter().any(|(_, t)| t.has_type_satisfies(f)),
|
||||
Self::Record(rec) => rec.values().any(f),
|
||||
Self::NamedTuple(rec) => rec.iter().any(|(_, t)| f(t)),
|
||||
Self::Poly { params, .. } => params.iter().any(|tp| tp.has_type_satisfies(f)),
|
||||
Self::Quantified(t) => t.has_type_satisfies(f),
|
||||
Self::Subr(subr) => {
|
||||
subr.non_default_params
|
||||
.iter()
|
||||
.any(|pt| pt.typ().has_type_satisfies(f))
|
||||
|| subr
|
||||
.var_params
|
||||
.as_ref()
|
||||
.map_or(false, |pt| pt.typ().has_type_satisfies(f))
|
||||
|| subr
|
||||
.default_params
|
||||
.iter()
|
||||
.any(|pt| pt.typ().has_type_satisfies(f))
|
||||
|| subr
|
||||
.default_params
|
||||
.iter()
|
||||
.any(|pt| pt.default_typ().map_or(false, |t| t.has_type_satisfies(f)))
|
||||
|| subr.return_t.has_type_satisfies(f)
|
||||
}
|
||||
// TODO: preds
|
||||
Self::Refinement(refine) => refine.t.has_type_satisfies(f),
|
||||
Self::Structural(ty) => ty.has_type_satisfies(f),
|
||||
Self::Proj { lhs, .. } => lhs.has_type_satisfies(f),
|
||||
Self::Quantified(t) => f(t),
|
||||
Self::Subr(subr) => subr.has_type_satisfies(f),
|
||||
Self::Refinement(refine) => f(&refine.t) || refine.pred.has_type_satisfies(f),
|
||||
Self::Structural(ty) => f(ty),
|
||||
Self::Proj { lhs, .. } => f(lhs),
|
||||
Self::ProjCall { lhs, args, .. } => {
|
||||
lhs.has_type_satisfies(f) || args.iter().any(|t| t.has_type_satisfies(f))
|
||||
lhs.has_type_satisfies(f) || args.iter().any(|tp| tp.has_type_satisfies(f))
|
||||
}
|
||||
Self::And(tys) => tys.iter().any(|t| t.has_type_satisfies(f)),
|
||||
Self::Or(tys) => tys.iter().any(|t| t.has_type_satisfies(f)),
|
||||
Self::Not(t) => t.has_type_satisfies(f),
|
||||
Self::Ref(t) => t.has_type_satisfies(f),
|
||||
Self::RefMut { before, after } => {
|
||||
before.has_type_satisfies(f)
|
||||
|| after.as_ref().map_or(false, |t| t.has_type_satisfies(f))
|
||||
}
|
||||
Self::Bounded { sub, sup } => sub.has_type_satisfies(f) || sup.has_type_satisfies(f),
|
||||
Self::Callable { param_ts, return_t } => {
|
||||
param_ts.iter().any(|t| t.has_type_satisfies(f)) || return_t.has_type_satisfies(f)
|
||||
}
|
||||
Self::Guard(guard) => guard.to.has_type_satisfies(f),
|
||||
Self::And(tys) => tys.iter().any(f),
|
||||
Self::Or(tys) => tys.iter().any(f),
|
||||
Self::Not(t) => f(t),
|
||||
Self::Ref(t) => f(t),
|
||||
Self::RefMut { before, after } => f(before) || after.as_ref().map_or(false, |t| f(t)),
|
||||
Self::Bounded { sub, sup } => f(sub) || f(sup),
|
||||
Self::Callable { param_ts, return_t } => param_ts.iter().any(f) || f(return_t),
|
||||
Self::Guard(guard) => f(&guard.to),
|
||||
mono_type_pattern!() => false,
|
||||
}
|
||||
}
|
||||
|
@ -3810,31 +3702,15 @@ impl Type {
|
|||
opt_t.map_or(false, |t| t.has_qvar())
|
||||
}
|
||||
}
|
||||
Self::Ref(ty) => ty.has_qvar(),
|
||||
Self::RefMut { before, after } => {
|
||||
before.has_qvar() || after.as_ref().map(|t| t.has_qvar()).unwrap_or(false)
|
||||
}
|
||||
Self::And(tys) => tys.iter().any(|t| t.has_qvar()),
|
||||
Self::Or(tys) => tys.iter().any(|t| t.has_qvar()),
|
||||
Self::Not(ty) => ty.has_qvar(),
|
||||
Self::Callable { param_ts, return_t } => {
|
||||
param_ts.iter().any(|t| t.has_qvar()) || return_t.has_qvar()
|
||||
}
|
||||
Self::Subr(subr) => subr.has_qvar(),
|
||||
Self::Quantified(_) => false,
|
||||
// Self::Quantified(quant) => quant.has_qvar(),
|
||||
Self::Record(r) => r.values().any(|t| t.has_qvar()),
|
||||
Self::NamedTuple(r) => r.iter().any(|(_, t)| t.has_qvar()),
|
||||
Self::Refinement(refine) => refine.t.has_qvar() || refine.pred.has_qvar(),
|
||||
Self::Poly { params, .. } => params.iter().any(|tp| tp.has_qvar()),
|
||||
Self::Proj { lhs, .. } => lhs.has_qvar(),
|
||||
Self::ProjCall { lhs, args, .. } => {
|
||||
lhs.has_qvar() || args.iter().any(|tp| tp.has_qvar())
|
||||
}
|
||||
Self::Structural(ty) => ty.has_qvar(),
|
||||
Self::Guard(guard) => guard.to.has_qvar(),
|
||||
Self::Bounded { sub, sup } => sub.has_qvar() || sup.has_qvar(),
|
||||
mono_type_pattern!() => false,
|
||||
_ => self.has_type_satisfies(|t| t.has_qvar()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3860,39 +3736,12 @@ impl Type {
|
|||
opt_t.map_or(false, |t| t.has_undoable_linked_var())
|
||||
}
|
||||
}
|
||||
Self::Ref(ty) => ty.has_undoable_linked_var(),
|
||||
Self::RefMut { before, after } => {
|
||||
before.has_undoable_linked_var()
|
||||
|| after
|
||||
.as_ref()
|
||||
.map(|t| t.has_undoable_linked_var())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
Self::And(tys) => tys.iter().any(|t| t.has_undoable_linked_var()),
|
||||
Self::Or(tys) => tys.iter().any(|t| t.has_undoable_linked_var()),
|
||||
Self::Not(ty) => ty.has_undoable_linked_var(),
|
||||
Self::Callable { param_ts, return_t } => {
|
||||
param_ts.iter().any(|t| t.has_undoable_linked_var())
|
||||
|| return_t.has_undoable_linked_var()
|
||||
}
|
||||
Self::Subr(subr) => subr.has_undoable_linked_var(),
|
||||
Self::Quantified(quant) => quant.has_undoable_linked_var(),
|
||||
Self::Record(r) => r.values().any(|t| t.has_undoable_linked_var()),
|
||||
Self::NamedTuple(r) => r.iter().any(|(_, t)| t.has_undoable_linked_var()),
|
||||
Self::Refinement(refine) => {
|
||||
refine.t.has_undoable_linked_var() || refine.pred.has_undoable_linked_var()
|
||||
}
|
||||
Self::Poly { params, .. } => params.iter().any(|tp| tp.has_undoable_linked_var()),
|
||||
Self::Proj { lhs, .. } => lhs.has_undoable_linked_var(),
|
||||
Self::ProjCall { lhs, args, .. } => {
|
||||
lhs.has_undoable_linked_var() || args.iter().any(|tp| tp.has_undoable_linked_var())
|
||||
}
|
||||
Self::Structural(ty) => ty.has_undoable_linked_var(),
|
||||
Self::Guard(guard) => guard.to.has_undoable_linked_var(),
|
||||
Self::Bounded { sub, sup } => {
|
||||
sub.has_undoable_linked_var() || sup.has_undoable_linked_var()
|
||||
}
|
||||
mono_type_pattern!() => false,
|
||||
_ => self.has_type_satisfies(|t| t.has_undoable_linked_var()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3903,45 +3752,13 @@ impl Type {
|
|||
pub fn has_unbound_var(&self) -> bool {
|
||||
match self {
|
||||
Self::FreeVar(fv) => fv.has_unbound_var(),
|
||||
Self::Ref(t) => t.has_unbound_var(),
|
||||
Self::RefMut { before, after } => {
|
||||
before.has_unbound_var()
|
||||
|| after.as_ref().map(|t| t.has_unbound_var()).unwrap_or(false)
|
||||
}
|
||||
Self::And(tys) => tys.iter().any(|t| t.has_unbound_var()),
|
||||
Self::Or(tys) => tys.iter().any(|t| t.has_unbound_var()),
|
||||
Self::Not(ty) => ty.has_unbound_var(),
|
||||
Self::Callable { param_ts, return_t } => {
|
||||
param_ts.iter().any(|t| t.has_unbound_var()) || return_t.has_unbound_var()
|
||||
}
|
||||
Self::Subr(subr) => {
|
||||
subr.non_default_params
|
||||
.iter()
|
||||
.any(|pt| pt.typ().has_unbound_var())
|
||||
|| subr
|
||||
.var_params
|
||||
.as_ref()
|
||||
.map(|pt| pt.typ().has_unbound_var())
|
||||
.unwrap_or(false)
|
||||
|| subr.default_params.iter().any(|pt| {
|
||||
pt.typ().has_unbound_var()
|
||||
|| pt.default_typ().is_some_and(|t| t.has_unbound_var())
|
||||
})
|
||||
|| subr.return_t.has_unbound_var()
|
||||
}
|
||||
Self::Record(r) => r.values().any(|t| t.has_unbound_var()),
|
||||
Self::NamedTuple(r) => r.iter().any(|(_, t)| t.has_unbound_var()),
|
||||
Self::Subr(subr) => subr.has_unbound_var(),
|
||||
Self::Refinement(refine) => refine.t.has_unbound_var() || refine.pred.has_unbound_var(),
|
||||
Self::Quantified(quant) => quant.has_unbound_var(),
|
||||
Self::Poly { params, .. } => params.iter().any(|p| p.has_unbound_var()),
|
||||
Self::Proj { lhs, .. } => lhs.has_unbound_var(),
|
||||
Self::ProjCall { lhs, args, .. } => {
|
||||
lhs.has_unbound_var() || args.iter().any(|t| t.has_unbound_var())
|
||||
}
|
||||
Self::Structural(ty) => ty.has_unbound_var(),
|
||||
Self::Guard(guard) => guard.to.has_unbound_var(),
|
||||
Self::Bounded { sub, sup } => sub.has_unbound_var() || sup.has_unbound_var(),
|
||||
mono_type_pattern!() => false,
|
||||
_ => self.has_type_satisfies(|t| t.has_unbound_var()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -656,7 +656,8 @@ impl Predicate {
|
|||
|
||||
pub fn qvars(&self) -> Set<(Str, Constraint)> {
|
||||
match self {
|
||||
Self::Value(_) | Self::Const(_) | Self::Failure => set! {},
|
||||
Self::Const(_) | Self::Failure => set! {},
|
||||
Self::Value(val) => val.qvars(),
|
||||
Self::Call { receiver, args, .. } => {
|
||||
let mut set = receiver.qvars();
|
||||
for arg in args {
|
||||
|
@ -680,9 +681,35 @@ impl Predicate {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn has_type_satisfies(&self, f: impl Fn(&Type) -> bool + Copy) -> bool {
|
||||
match self {
|
||||
Self::Const(_) | Self::Failure => false,
|
||||
Self::Value(val) => val.has_type_satisfies(f),
|
||||
Self::Call { receiver, args, .. } => {
|
||||
receiver.has_type_satisfies(f) || args.iter().any(|a| a.has_type_satisfies(f))
|
||||
}
|
||||
Self::Attr { receiver, .. } => receiver.has_type_satisfies(f),
|
||||
Self::Equal { rhs, .. }
|
||||
| Self::GreaterEqual { rhs, .. }
|
||||
| Self::LessEqual { rhs, .. }
|
||||
| Self::NotEqual { rhs, .. } => rhs.has_type_satisfies(f),
|
||||
Self::GeneralEqual { lhs, rhs }
|
||||
| Self::GeneralLessEqual { lhs, rhs }
|
||||
| Self::GeneralGreaterEqual { lhs, rhs }
|
||||
| Self::GeneralNotEqual { lhs, rhs } => {
|
||||
lhs.has_type_satisfies(f) || rhs.has_type_satisfies(f)
|
||||
}
|
||||
Self::Or(lhs, rhs) | Self::And(lhs, rhs) => {
|
||||
lhs.has_type_satisfies(f) || rhs.has_type_satisfies(f)
|
||||
}
|
||||
Self::Not(pred) => pred.has_type_satisfies(f),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_qvar(&self) -> bool {
|
||||
match self {
|
||||
Self::Value(_) | Self::Const(_) | Self::Failure => false,
|
||||
Self::Const(_) | Self::Failure => false,
|
||||
Self::Value(val) => val.has_qvar(),
|
||||
Self::Call { receiver, args, .. } => {
|
||||
receiver.has_qvar() || args.iter().any(|a| a.has_qvar())
|
||||
}
|
||||
|
@ -702,7 +729,8 @@ impl Predicate {
|
|||
|
||||
pub fn has_unbound_var(&self) -> bool {
|
||||
match self {
|
||||
Self::Value(_) | Self::Const(_) | Self::Failure => false,
|
||||
Self::Const(_) | Self::Failure => false,
|
||||
Self::Value(val) => val.has_unbound_var(),
|
||||
Self::Call { receiver, args, .. } => {
|
||||
receiver.has_unbound_var() || args.iter().any(|a| a.has_unbound_var())
|
||||
}
|
||||
|
@ -724,7 +752,8 @@ impl Predicate {
|
|||
|
||||
pub fn has_undoable_linked_var(&self) -> bool {
|
||||
match self {
|
||||
Self::Value(_) | Self::Const(_) | Self::Failure => false,
|
||||
Self::Const(_) | Self::Failure => false,
|
||||
Self::Value(val) => val.has_undoable_linked_var(),
|
||||
Self::Call { receiver, args, .. } => {
|
||||
receiver.has_undoable_linked_var()
|
||||
|| args.iter().any(|a| a.has_undoable_linked_var())
|
||||
|
|
|
@ -1268,21 +1268,21 @@ impl TyParam {
|
|||
pub fn has_type_satisfies(&self, f: impl Fn(&Type) -> bool + Copy) -> bool {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => fv.crack().has_type_satisfies(f),
|
||||
Self::FreeVar(fv) => fv.get_type().map_or(false, |t| t.has_type_satisfies(f)),
|
||||
Self::Type(t) => t.has_type_satisfies(f),
|
||||
Self::Erased(t) => t.has_type_satisfies(f),
|
||||
Self::FreeVar(fv) => fv.get_type().map_or(false, |t| f(&t)),
|
||||
Self::Type(t) => f(t),
|
||||
Self::Erased(t) => f(t),
|
||||
Self::Proj { obj, .. } => obj.has_type_satisfies(f),
|
||||
Self::ProjCall { obj, args, .. } => {
|
||||
obj.has_type_satisfies(f) || args.iter().any(|t| t.has_type_satisfies(f))
|
||||
obj.has_type_satisfies(f) || args.iter().any(|tp| tp.has_type_satisfies(f))
|
||||
}
|
||||
Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.has_type_satisfies(f)),
|
||||
Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|tp| tp.has_type_satisfies(f)),
|
||||
Self::UnsizedList(elem) => elem.has_type_satisfies(f),
|
||||
Self::Set(ts) => ts.iter().any(|t| t.has_type_satisfies(f)),
|
||||
Self::Set(ts) => ts.iter().any(|tp| tp.has_type_satisfies(f)),
|
||||
Self::Dict(ts) => ts
|
||||
.iter()
|
||||
.any(|(k, v)| k.has_type_satisfies(f) || v.has_type_satisfies(f)),
|
||||
Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
|
||||
rec.iter().any(|(_, tp)| tp.has_type_satisfies(f))
|
||||
rec.values().any(|tp| tp.has_type_satisfies(f))
|
||||
}
|
||||
Self::Lambda(lambda) => lambda.body.iter().any(|tp| tp.has_type_satisfies(f)),
|
||||
Self::UnaryOp { val, .. } => val.has_type_satisfies(f),
|
||||
|
|
|
@ -2080,7 +2080,7 @@ impl ValueObj {
|
|||
|
||||
pub fn has_type_satisfies(&self, f: impl Fn(&Type) -> bool + Copy) -> bool {
|
||||
match self {
|
||||
Self::Type(t) => t.typ().has_type_satisfies(f),
|
||||
Self::Type(t) => f(t.typ()),
|
||||
Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.has_type_satisfies(f)),
|
||||
Self::UnsizedList(elem) => elem.has_type_satisfies(f),
|
||||
Self::Set(ts) => ts.iter().any(|t| t.has_type_satisfies(f)),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue