dev: don't use bug prone ever_be (#280)

This commit is contained in:
Myriad-Dreamin 2024-05-13 21:29:59 +08:00 committed by GitHub
parent f66d50c51f
commit 66e6aff2b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 52 additions and 29 deletions

View file

@ -81,7 +81,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
w w
} }
fn get_var(&mut self, s: Span, r: IdentRef) -> Option<&mut TypeVarBounds> { fn get_var(&mut self, s: Span, r: IdentRef) -> Option<Ty> {
let def_id = self let def_id = self
.def_use_info .def_use_info
.get_ref(&r) .get_ref(&r)
@ -107,7 +107,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
let var = self.info.vars.get_mut(&def_id).unwrap(); let var = self.info.vars.get_mut(&def_id).unwrap();
TypeCheckInfo::witness_(s, var.as_type(), &mut self.info.mapping); TypeCheckInfo::witness_(s, var.as_type(), &mut self.info.mapping);
Some(var) Some(var.as_type())
} }
fn import_ty(&mut self, def_id: DefId) -> Option<Ty> { fn import_ty(&mut self, def_id: DefId) -> Option<Ty> {
@ -149,6 +149,10 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
} }
} }
if lhs == rhs {
return;
}
match (lhs, rhs) { match (lhs, rhs) {
(Ty::Var(v), Ty::Var(w)) => { (Ty::Var(v), Ty::Var(w)) => {
if v.def == w.def { if v.def == w.def {

View file

@ -186,13 +186,11 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
range: root.range(), range: root.range(),
}; };
let Some(var) = self.get_var(root.span(), ident_ref) else { self.get_var(root.span(), ident_ref).or_else(|| {
let s = root.span(); let s = root.span();
let v = resolve_global_value(self.ctx, root, mode == InterpretMode::Math)?; let v = resolve_global_value(self.ctx, root, mode == InterpretMode::Math)?;
return Some(Ty::Value(InsTy::new_at(v, s))); Some(Ty::Value(InsTy::new_at(v, s)))
}; })
Some(var.as_type())
} }
fn check_array(&mut self, root: LinkedNode<'_>) -> Option<Ty> { fn check_array(&mut self, root: LinkedNode<'_>) -> Option<Ty> {
@ -377,16 +375,18 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
ast::Param::Named(e) => { ast::Param::Named(e) => {
let exp = self.check_expr_in(e.expr().span(), root.clone()); let exp = self.check_expr_in(e.expr().span(), root.clone());
let v = self.get_var(e.name().span(), to_ident_ref(&root, e.name())?)?; let v = self.get_var(e.name().span(), to_ident_ref(&root, e.name())?)?;
v.ever_be(exp); // todo: this is less efficient than v.lbs.push(exp), we may have some idea to
named.insert(e.name().into(), v.as_type()); // optimize it, so I put a todo here.
self.constrain(&exp, &v);
named.insert(e.name().into(), v);
} }
// todo: spread left/right // todo: spread left/right
ast::Param::Spread(a) => { ast::Param::Spread(a) => {
if let Some(e) = a.sink_ident() { if let Some(e) = a.sink_ident() {
let exp = Ty::Builtin(BuiltinTy::Args); let exp = Ty::Builtin(BuiltinTy::Args);
let v = self.get_var(e.span(), to_ident_ref(&root, e)?)?; let v = self.get_var(e.span(), to_ident_ref(&root, e)?)?;
v.ever_be(exp); self.constrain(&exp, &v);
rest = Some(v.as_type()); rest = Some(v);
} }
// todo: ..(args) // todo: ..(args)
} }
@ -424,7 +424,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
.unwrap_or_else(|| Ty::Infer); .unwrap_or_else(|| Ty::Infer);
let v = self.get_var(c.span(), to_ident_ref(&root, c)?)?; let v = self.get_var(c.span(), to_ident_ref(&root, c)?)?;
v.ever_be(value); self.constrain(&value, &v);
// todo lbs is the lexical signature. // todo lbs is the lexical signature.
} }
ast::LetBindingKind::Normal(pattern) => { ast::LetBindingKind::Normal(pattern) => {
@ -560,8 +560,8 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
Some(match pattern { Some(match pattern {
ast::Pattern::Normal(ast::Expr::Ident(ident)) => { ast::Pattern::Normal(ast::Expr::Ident(ident)) => {
let v = self.get_var(ident.span(), to_ident_ref(&root, ident)?)?; let v = self.get_var(ident.span(), to_ident_ref(&root, ident)?)?;
v.ever_be(value); self.constrain(&value, &v);
v.as_type() v
} }
ast::Pattern::Normal(_) => Ty::Any, ast::Pattern::Normal(_) => Ty::Any,
ast::Pattern::Placeholder(_) => Ty::Any, ast::Pattern::Placeholder(_) => Ty::Any,

View file

@ -0,0 +1,8 @@
#let x(date) = date.display()
#let (x: x) = (x: 1)
#let master-cover(info, x: x) = {
info = (submit-date: 0) + info
x(datetime.today())
}

View file

@ -0,0 +1,24 @@
---
source: crates/tinymist-query/src/analysis.rs
expression: result
input_file: crates/tinymist-query/src/fixtures/type_check/confusing-name.typ
---
"date" = Any
"info" = Any
"master-cover" = (Any, "x": Any) => TypeBinary { operands: (Any, TypeBinary { operands: ({"submit-date": 0}, Any), op: Add }), op: Assign }
"x" = Any
"x" = (Any) => Any
---
5..6 -> @x
7..11 -> @date
15..19 -> @date
15..29 -> Any
57..69 -> @master-cover
70..74 -> @info
76..77 -> @x
79..80 -> @x
88..92 -> @info
114..118 -> @info
121..122 -> @x
121..140 -> Any
123..139 -> Any

View file

@ -292,10 +292,7 @@ pub struct TypeVarBounds {
impl fmt::Debug for TypeVarBounds { impl fmt::Debug for TypeVarBounds {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.var)?; write!(f, "{:?}", self.var)
match &self.bounds {
FlowVarKind::Strong(w) | FlowVarKind::Weak(w) => write!(f, "{w:?}"),
}
} }
} }
@ -319,16 +316,6 @@ impl TypeVarBounds {
} }
} }
pub fn ever_be(&self, exp: Ty) {
match &self.bounds {
// FlowVarKind::Strong(_t) => {}
FlowVarKind::Strong(w) | FlowVarKind::Weak(w) => {
let mut w = w.write();
w.lbs.push(exp.clone());
}
}
}
pub(crate) fn weaken(&mut self) { pub(crate) fn weaken(&mut self) {
match &self.bounds { match &self.bounds {
FlowVarKind::Strong(w) => { FlowVarKind::Strong(w) => {
@ -793,7 +780,7 @@ impl fmt::Debug for Ty {
} }
Ty::Let(v) => write!(f, "({v:?})"), Ty::Let(v) => write!(f, "({v:?})"),
Ty::Field(ff) => write!(f, "{:?}: {:?}", ff.name, ff.field), Ty::Field(ff) => write!(f, "{:?}: {:?}", ff.name, ff.field),
Ty::Var(v) => write!(f, "@{}", v.name()), Ty::Var(v) => v.fmt(f),
Ty::Unary(u) => write!(f, "{u:?}"), Ty::Unary(u) => write!(f, "{u:?}"),
Ty::Binary(b) => write!(f, "{b:?}"), Ty::Binary(b) => write!(f, "{b:?}"),
Ty::If(i) => write!(f, "{i:?}"), Ty::If(i) => write!(f, "{i:?}"),