diff --git a/crates/tinymist-query/src/analysis/ty.rs b/crates/tinymist-query/src/analysis/ty.rs index 2016d5c2..c302e6db 100644 --- a/crates/tinymist-query/src/analysis/ty.rs +++ b/crates/tinymist-query/src/analysis/ty.rs @@ -81,7 +81,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> { w } - fn get_var(&mut self, s: Span, r: IdentRef) -> Option<&mut TypeVarBounds> { + fn get_var(&mut self, s: Span, r: IdentRef) -> Option { let def_id = self .def_use_info .get_ref(&r) @@ -107,7 +107,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> { let var = self.info.vars.get_mut(&def_id).unwrap(); 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 { @@ -149,6 +149,10 @@ impl<'a, 'w> TypeChecker<'a, 'w> { } } + if lhs == rhs { + return; + } + match (lhs, rhs) { (Ty::Var(v), Ty::Var(w)) => { if v.def == w.def { diff --git a/crates/tinymist-query/src/analysis/ty/syntax.rs b/crates/tinymist-query/src/analysis/ty/syntax.rs index 0e185c22..0a11e4a3 100644 --- a/crates/tinymist-query/src/analysis/ty/syntax.rs +++ b/crates/tinymist-query/src/analysis/ty/syntax.rs @@ -186,13 +186,11 @@ impl<'a, 'w> TypeChecker<'a, 'w> { 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 v = resolve_global_value(self.ctx, root, mode == InterpretMode::Math)?; - return Some(Ty::Value(InsTy::new_at(v, s))); - }; - - Some(var.as_type()) + Some(Ty::Value(InsTy::new_at(v, s))) + }) } fn check_array(&mut self, root: LinkedNode<'_>) -> Option { @@ -377,16 +375,18 @@ impl<'a, 'w> TypeChecker<'a, 'w> { ast::Param::Named(e) => { 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())?)?; - v.ever_be(exp); - named.insert(e.name().into(), v.as_type()); + // todo: this is less efficient than v.lbs.push(exp), we may have some idea to + // optimize it, so I put a todo here. + self.constrain(&exp, &v); + named.insert(e.name().into(), v); } // todo: spread left/right ast::Param::Spread(a) => { if let Some(e) = a.sink_ident() { let exp = Ty::Builtin(BuiltinTy::Args); let v = self.get_var(e.span(), to_ident_ref(&root, e)?)?; - v.ever_be(exp); - rest = Some(v.as_type()); + self.constrain(&exp, &v); + rest = Some(v); } // todo: ..(args) } @@ -424,7 +424,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> { .unwrap_or_else(|| Ty::Infer); 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. } ast::LetBindingKind::Normal(pattern) => { @@ -560,8 +560,8 @@ impl<'a, 'w> TypeChecker<'a, 'w> { Some(match pattern { ast::Pattern::Normal(ast::Expr::Ident(ident)) => { let v = self.get_var(ident.span(), to_ident_ref(&root, ident)?)?; - v.ever_be(value); - v.as_type() + self.constrain(&value, &v); + v } ast::Pattern::Normal(_) => Ty::Any, ast::Pattern::Placeholder(_) => Ty::Any, diff --git a/crates/tinymist-query/src/fixtures/type_check/confusing-name.typ b/crates/tinymist-query/src/fixtures/type_check/confusing-name.typ new file mode 100644 index 00000000..a6280997 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/type_check/confusing-name.typ @@ -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()) +} + diff --git a/crates/tinymist-query/src/fixtures/type_check/snaps/test@confusing-name.typ.snap b/crates/tinymist-query/src/fixtures/type_check/snaps/test@confusing-name.typ.snap new file mode 100644 index 00000000..1794486b --- /dev/null +++ b/crates/tinymist-query/src/fixtures/type_check/snaps/test@confusing-name.typ.snap @@ -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 diff --git a/crates/tinymist-query/src/ty/def.rs b/crates/tinymist-query/src/ty/def.rs index ccb05706..be9e4d5d 100644 --- a/crates/tinymist-query/src/ty/def.rs +++ b/crates/tinymist-query/src/ty/def.rs @@ -292,10 +292,7 @@ pub struct TypeVarBounds { impl fmt::Debug for TypeVarBounds { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.var)?; - match &self.bounds { - FlowVarKind::Strong(w) | FlowVarKind::Weak(w) => write!(f, "{w:?}"), - } + write!(f, "{:?}", self.var) } } @@ -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) { match &self.bounds { FlowVarKind::Strong(w) => { @@ -793,7 +780,7 @@ impl fmt::Debug for Ty { } Ty::Let(v) => write!(f, "({v:?})"), 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::Binary(b) => write!(f, "{b:?}"), Ty::If(i) => write!(f, "{i:?}"),