tinymist/crates/tinymist-query/src/ty/bound.rs
Myriad-Dreamin fff227f3ae
dev: interning types (#271)
* refactor: a bit

* fix: named completion

* dev: replace complete_literal by complete_type

* dev: remove unused code

* dev: basic interner

* dev: basic types

* dev: type operations

* dev: migrate all type definitions

* dev: check syntax and builtin types

* dev: make TypeSimplifier simply work

* dev: make TypeDescriber simply work

* dev: make TypeChecker simply work

* dev: recover type check

* fix: context check

* fix: use after free in seen fields

* fix: typed with

* fix: record type on field

* dev: check type of constructors and element containing

* dev: show sig by type

* fix: mixed context checking

* QAQ

* >_<

* dev: fix documents
2024-05-11 21:12:49 +08:00

68 lines
1.8 KiB
Rust

use crate::{adt::interner::Interned, ty::def::*};
pub trait BoundChecker {
fn collect(&mut self, ty: &Ty, pol: bool);
fn bound_of_var(&mut self, _var: &Interned<TypeVar>, _pol: bool) -> Option<TypeBounds> {
None
}
}
impl<T> BoundChecker for T
where
T: FnMut(&Ty, bool) -> Option<TypeBounds>,
{
fn collect(&mut self, ty: &Ty, pol: bool) {
self(ty, pol);
}
}
impl Ty {
pub fn has_bounds(&self) -> bool {
matches!(self, Ty::Union(_) | Ty::Let(_) | Ty::Var(_))
}
pub fn bounds(&self, pol: bool, checker: &mut impl BoundChecker) {
let mut worker = BoundCheckContext;
worker.ty(self, pol, checker);
}
}
pub struct BoundCheckContext;
impl BoundCheckContext {
fn tys<'a>(
&mut self,
tys: impl Iterator<Item = &'a Ty>,
pol: bool,
checker: &mut impl BoundChecker,
) {
for ty in tys {
self.ty(ty, pol, checker);
}
}
fn ty(&mut self, ty: &Ty, pol: bool, checker: &mut impl BoundChecker) {
match ty {
Ty::Union(u) => {
self.tys(u.iter(), pol, checker);
}
Ty::Let(u) => {
self.tys(u.ubs.iter(), pol, checker);
self.tys(u.lbs.iter(), !pol, checker);
}
Ty::Var(u) => {
let Some(w) = checker.bound_of_var(u, pol) else {
return;
};
self.tys(w.ubs.iter(), pol, checker);
self.tys(w.lbs.iter(), !pol, checker);
}
// todo: calculate these operators
// Ty::Select(_) => {}
// Ty::Unary(_) => {}
// Ty::Binary(_) => {}
// Ty::If(_) => {}
ty => checker.collect(ty, pol),
}
}
}