From 57c6c7a4f6699b1134be85bb2c8bcc677c74bde9 Mon Sep 17 00:00:00 2001 From: Myriad-Dreamin <35292584+Myriad-Dreamin@users.noreply.github.com> Date: Sat, 16 Nov 2024 13:50:50 +0800 Subject: [PATCH] dev: replace `FieldTy` with `ParamTy` (#830) --- .../tinymist-query/src/analysis/post_tyck.rs | 8 +- crates/tinymist-query/src/analysis/prelude.rs | 1 - .../tinymist-query/src/analysis/signature.rs | 141 +++++------------- crates/tinymist-query/src/analysis/tyck.rs | 8 +- crates/tinymist-query/src/docs/def.rs | 4 +- crates/tinymist-query/src/signature_help.rs | 2 +- crates/tinymist-query/src/ty/bound.rs | 5 +- crates/tinymist-query/src/ty/def.rs | 133 +++++++++++++++-- crates/tinymist-query/src/ty/describe.rs | 4 +- crates/tinymist-query/src/ty/iface.rs | 4 - crates/tinymist-query/src/ty/mutate.rs | 8 +- crates/tinymist-query/src/ty/sig.rs | 4 + crates/tinymist-query/src/ty/simplify.rs | 10 +- .../src/upstream/complete/ext.rs | 2 +- 14 files changed, 188 insertions(+), 146 deletions(-) diff --git a/crates/tinymist-query/src/analysis/post_tyck.rs b/crates/tinymist-query/src/analysis/post_tyck.rs index 806821dd..4312158b 100644 --- a/crates/tinymist-query/src/analysis/post_tyck.rs +++ b/crates/tinymist-query/src/analysis/post_tyck.rs @@ -3,9 +3,9 @@ use hashbrown::HashSet; use tinymist_derive::BindTyCtx; -use super::{prelude::*, SharedContext}; +use super::{prelude::*, ParamAttrs, SharedContext}; use super::{ - ArgsTy, FieldTy, Sig, SigChecker, SigShape, SigSurfaceKind, SigTy, Ty, TyCtx, TyCtxMut, + ArgsTy, ParamTy, Sig, SigChecker, SigShape, SigSurfaceKind, SigTy, Ty, TyCtx, TyCtxMut, TypeBounds, TypeScheme, TypeVar, }; use crate::syntax::{get_check_target, get_check_target_by_context, CheckTarget, ParamTarget}; @@ -82,8 +82,8 @@ fn check_signature<'a>( // names for (name, _) in sig_ins.named_params() { // todo: reduce fields, fields ty - let field = FieldTy::new_untyped(name.clone()); - receiver.insert(&Ty::Field(field), !pol); + let field = ParamTy::new_untyped(name.clone(), ParamAttrs::named()); + receiver.insert(&Ty::Param(field), !pol); } Some(()) diff --git a/crates/tinymist-query/src/analysis/prelude.rs b/crates/tinymist-query/src/analysis/prelude.rs index cb8f6bcb..423f1e7d 100644 --- a/crates/tinymist-query/src/analysis/prelude.rs +++ b/crates/tinymist-query/src/analysis/prelude.rs @@ -7,7 +7,6 @@ pub use std::sync::{Arc, LazyLock}; pub use comemo::Track; pub use ecow::*; -pub use serde::{Deserialize, Serialize}; pub use typst::foundations::{Func, Value}; pub use typst::syntax::ast::{self, AstNode}; pub use typst::syntax::{FileId as TypstFileId, LinkedNode, Source, Span, SyntaxKind, SyntaxNode}; diff --git a/crates/tinymist-query/src/analysis/signature.rs b/crates/tinymist-query/src/analysis/signature.rs index 8cd3add2..d87972b2 100644 --- a/crates/tinymist-query/src/analysis/signature.rs +++ b/crates/tinymist-query/src/analysis/signature.rs @@ -2,89 +2,19 @@ use itertools::Either; use tinymist_derive::BindTyCtx; -use typst::foundations::{Closure, ParamInfo}; +use typst::foundations::Closure; use super::{ - prelude::*, BoundChecker, Definition, DocSource, SharedContext, SigTy, SigWithTy, TypeVar, + prelude::*, BoundChecker, Definition, DocSource, ParamTy, SharedContext, SigTy, SigWithTy, + TypeScheme, TypeVar, }; use crate::analysis::PostTypeChecker; use crate::docs::{UntypedDefDocs, UntypedSignatureDocs, UntypedVarDocs}; use crate::syntax::get_non_strict_def_target; -use crate::ty::TypeBounds; use crate::ty::{InsTy, TyCtx}; +use crate::ty::{ParamAttrs, TypeBounds}; use crate::upstream::truncated_repr; -/// Describes a function parameter. -#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)] -pub struct ParamAttrs { - /// Is the parameter positional? - pub positional: bool, - /// Is the parameter named? - /// - /// Can be true even if `positional` is true if the parameter can be given - /// in both variants. - pub named: bool, - /// Can the parameter be given any number of times? - pub variadic: bool, - /// Is the parameter settable with a set rule? - pub settable: bool, -} - -impl ParamAttrs { - pub(crate) fn positional() -> ParamAttrs { - ParamAttrs { - positional: true, - named: false, - variadic: false, - settable: false, - } - } - - pub(crate) fn named() -> ParamAttrs { - ParamAttrs { - positional: false, - named: true, - variadic: false, - settable: false, - } - } - - pub(crate) fn variadic() -> ParamAttrs { - ParamAttrs { - positional: true, - named: false, - variadic: true, - settable: false, - } - } -} - -impl From<&ParamInfo> for ParamAttrs { - fn from(param: &ParamInfo) -> Self { - ParamAttrs { - positional: param.positional, - named: param.named, - variadic: param.variadic, - settable: param.settable, - } - } -} - -/// Describes a function parameter. -#[derive(Debug, Clone)] -pub struct ParamSpec { - /// The name of the parameter. - pub name: StrRef, - /// The docstring of the parameter. - pub docs: Option, - /// The default value of the variable - pub default: Option, - /// The type of the parameter. - pub ty: Ty, - /// The attributes of the parameter. - pub attrs: ParamAttrs, -} - /// Describes a function signature. #[derive(Debug, Clone)] pub enum Signature { @@ -112,7 +42,7 @@ impl Signature { } /// Returns the all parameters of the function. - pub(crate) fn params(&self) -> impl Iterator)> { + pub(crate) fn params(&self) -> impl Iterator, Option<&Ty>)> { let primary = self.primary().params(); // todo: with stack primary @@ -124,7 +54,7 @@ impl Signature { primary } - pub(crate) fn param_shift(&self, _ctx: &mut LocalContext) -> usize { + pub(crate) fn param_shift(&self) -> usize { match self { Signature::Primary(_) => 0, Signature::Partial(sig) => sig @@ -142,7 +72,7 @@ pub struct PrimarySignature { /// The documentation of the function pub docs: Option, /// The documentation of the parameter. - pub param_specs: Vec, + pub param_specs: Vec>, /// Whether the function has fill, stroke, or size parameters. pub has_fill_or_size_or_stroke: bool, /// The associated signature type. @@ -162,22 +92,22 @@ impl PrimarySignature { } /// Returns the positional parameters of the function. - pub fn pos(&self) -> &[ParamSpec] { + pub fn pos(&self) -> &[Interned] { &self.param_specs[..self.pos_size()] } /// Returns the positional parameters of the function. - pub fn get_pos(&self, offset: usize) -> Option<&ParamSpec> { + pub fn get_pos(&self, offset: usize) -> Option<&Interned> { self.pos().get(offset) } /// Returns the named parameters of the function. - pub fn named(&self) -> &[ParamSpec] { + pub fn named(&self) -> &[Interned] { &self.param_specs[self.pos_size()..self.pos_size() + self.sig_ty.names.names.len()] } /// Returns the named parameters of the function. - pub fn get_named(&self, name: &StrRef) -> Option<&ParamSpec> { + pub fn get_named(&self, name: &StrRef) -> Option<&Interned> { self.named().get(self.sig_ty.names.find(name)?) } @@ -187,13 +117,13 @@ impl PrimarySignature { } /// Returns the rest parameter of the function. - pub fn rest(&self) -> Option<&ParamSpec> { + pub fn rest(&self) -> Option<&Interned> { self.has_spread_right() .then(|| &self.param_specs[self.pos_size() + self.sig_ty.names.names.len()]) } /// Returns the all parameters of the function. - pub fn params(&self) -> impl Iterator)> { + pub fn params(&self) -> impl Iterator, Option<&Ty>)> { let pos = self.pos(); let named = self.named(); let rest = self.rest(); @@ -287,6 +217,14 @@ fn analyze_type_signature( } }?; + sig_of_type(ctx, &type_info, ty) +} + +pub(crate) fn sig_of_type( + ctx: &Arc, + type_info: &TypeScheme, + ty: Ty, +) -> Option { // todo multiple sources let mut srcs = ty.sources(); srcs.sort(); @@ -294,7 +232,7 @@ fn analyze_type_signature( let type_var = srcs.into_iter().next()?; match type_var { DocSource::Var(v) => { - let mut ty_ctx = PostTypeChecker::new(ctx.clone(), &type_info); + let mut ty_ctx = PostTypeChecker::new(ctx.clone(), type_info); let sig_ty = Ty::Func(ty.sig_repr(true, &mut ty_ctx)?); let sig_ty = type_info.simplify(sig_ty, false); let Ty::Func(sig_ty) = sig_ty else { @@ -330,13 +268,13 @@ fn analyze_type_signature( has_fill_or_size_or_stroke = true; } - param_specs.push(ParamSpec { + param_specs.push(Interned::new(ParamTy { name, docs: Some(doc.docs.clone()), default, ty, attrs: ParamAttrs::positional(), - }); + })); } for (name, ty) in sig_ty.named_params() { @@ -348,25 +286,25 @@ fn analyze_type_signature( has_fill_or_size_or_stroke = true; } - param_specs.push(ParamSpec { + param_specs.push(Interned::new(ParamTy { name: name.clone(), docs: Some(doc.docs.clone()), default, ty, attrs: ParamAttrs::named(), - }); + })); } if let Some(doc) = docstring.rest.as_ref() { let default = doc.default.clone(); - param_specs.push(ParamSpec { + param_specs.push(Interned::new(ParamTy { name: doc.name.clone(), docs: Some(doc.docs.clone()), default, ty: sig_ty.rest_param().cloned().unwrap_or(Ty::Any), attrs: ParamAttrs::variadic(), - }); + })); } let sig = Signature::Primary(Arc::new(PrimarySignature { @@ -568,7 +506,7 @@ fn analyze_dyn_signature_inner(func: Func) -> Arc { let mut broken = false; let mut has_fill_or_size_or_stroke = false; - let mut add_param = |param: ParamSpec| { + let mut add_param = |param: Interned| { let name = param.name.clone(); if param.attrs.named { if matches!(name.as_ref(), "fill" | "stroke" | "size") { @@ -601,13 +539,13 @@ fn analyze_dyn_signature_inner(func: Func) -> Arc { } Repr::Element(..) | Repr::Native(..) => { for p in func.params().unwrap() { - add_param(ParamSpec { + add_param(Interned::new(ParamTy { name: p.name.into(), docs: Some(p.docs.into()), default: p.default.map(|d| truncated_repr(&d())), ty: Ty::from_param_site(&func, p), attrs: p.into(), - }); + })); } func.returns().map(|r| Ty::from_return_site(&func, r)) @@ -632,7 +570,10 @@ fn analyze_dyn_signature_inner(func: Func) -> Arc { }) } -fn analyze_closure_signature(c: Arc>, add_param: &mut impl FnMut(ParamSpec)) { +fn analyze_closure_signature( + c: Arc>, + add_param: &mut impl FnMut(Interned), +) { log::trace!("closure signature for: {:?}", c.node.kind()); let closure = &c.node; @@ -645,34 +586,34 @@ fn analyze_closure_signature(c: Arc>, add_param: &mut impl FnM match param { ast::Param::Pos(e) => { let name = format!("{}", PatternDisplay(&e)); - add_param(ParamSpec { + add_param(Interned::new(ParamTy { name: name.as_str().into(), docs: None, default: None, ty: Ty::Any, attrs: ParamAttrs::positional(), - }); + })); } // todo: pattern ast::Param::Named(n) => { let expr = unwrap_expr(n.expr()).to_untyped().clone().into_text(); - add_param(ParamSpec { + add_param(Interned::new(ParamTy { name: n.name().get().into(), docs: Some(eco_format!("Default value: {expr}")), default: Some(expr), ty: Ty::Any, attrs: ParamAttrs::named(), - }); + })); } ast::Param::Spread(n) => { let ident = n.sink_ident().map(|e| e.as_str()); - add_param(ParamSpec { + add_param(Interned::new(ParamTy { name: ident.unwrap_or_default().into(), docs: None, default: None, ty: Ty::Any, attrs: ParamAttrs::variadic(), - }); + })); } } } diff --git a/crates/tinymist-query/src/analysis/tyck.rs b/crates/tinymist-query/src/analysis/tyck.rs index a7d48d92..7acbc1e6 100644 --- a/crates/tinymist-query/src/analysis/tyck.rs +++ b/crates/tinymist-query/src/analysis/tyck.rs @@ -399,8 +399,8 @@ impl<'a> TypeChecker<'a> { w.weaken(); } Ty::Any | Ty::Boolean(_) | Ty::Builtin(_) | Ty::Value(_) => {} - Ty::Field(v) => { - self.weaken(&v.field); + Ty::Param(v) => { + self.weaken(&v.ty); } Ty::Func(v) | Ty::Args(v) | Ty::Pattern(v) => { for ty in v.inputs() { @@ -540,8 +540,8 @@ impl Joiner { (Ty::Union(..), _) => self.definite = Ty::undef(), (Ty::Let(w), Ty::Builtin(BuiltinTy::None)) => self.definite = Ty::Let(w), (Ty::Let(..), _) => self.definite = Ty::undef(), - (Ty::Field(w), Ty::Builtin(BuiltinTy::None)) => self.definite = Ty::Field(w), - (Ty::Field(..), _) => self.definite = Ty::undef(), + (Ty::Param(w), Ty::Builtin(BuiltinTy::None)) => self.definite = Ty::Param(w), + (Ty::Param(..), _) => self.definite = Ty::undef(), (Ty::Boolean(b), Ty::Builtin(BuiltinTy::None)) => self.definite = Ty::Boolean(b), (Ty::Boolean(..), _) => self.definite = Ty::undef(), } diff --git a/crates/tinymist-query/src/docs/def.rs b/crates/tinymist-query/src/docs/def.rs index 7ed8fbe7..292de008 100644 --- a/crates/tinymist-query/src/docs/def.rs +++ b/crates/tinymist-query/src/docs/def.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use typst::syntax::Span; use super::tidy::*; -use crate::analysis::{ParamAttrs, ParamSpec, Signature}; +use crate::analysis::{ParamAttrs, ParamTy, Signature}; use crate::prelude::*; use crate::ty::Ty; use crate::ty::{DocSource, Interned}; @@ -279,7 +279,7 @@ pub struct ParamDocsT { } impl ParamDocs { - fn new(param: &ParamSpec, ty: Option<&Ty>) -> Self { + fn new(param: &ParamTy, ty: Option<&Ty>) -> Self { Self { name: param.name.as_ref().into(), docs: param.docs.clone().unwrap_or_default(), diff --git a/crates/tinymist-query/src/signature_help.rs b/crates/tinymist-query/src/signature_help.rs index be470892..ddf748d1 100644 --- a/crates/tinymist-query/src/signature_help.rs +++ b/crates/tinymist-query/src/signature_help.rs @@ -43,7 +43,7 @@ impl SemanticRequest for SignatureHelpRequest { let sig = ctx.sig_of_def(def.clone())?; log::debug!("got signature {sig:?}"); - let param_shift = sig.param_shift(ctx); + let param_shift = sig.param_shift(); let mut active_parameter = None; let mut label = def.name().as_ref().to_owned(); diff --git a/crates/tinymist-query/src/ty/bound.rs b/crates/tinymist-query/src/ty/bound.rs index 238bd9ed..fdde51a0 100644 --- a/crates/tinymist-query/src/ty/bound.rs +++ b/crates/tinymist-query/src/ty/bound.rs @@ -78,8 +78,9 @@ impl Ty { Any | Boolean(_) | If(..) | Builtin(..) | Value(..) => {} Dict(..) | Array(..) | Tuple(..) | Func(..) | Args(..) | Pattern(..) => {} Unary(..) | Binary(..) => {} - Field(ty) => { - collect(&ty.field, results); + Param(ty) => { + // todo: doc source can be param ty + collect(&ty.ty, results); } Union(ty) => { for ty in ty.iter() { diff --git a/crates/tinymist-query/src/ty/def.rs b/crates/tinymist-query/src/ty/def.rs index c5dc042a..4f0f32b2 100644 --- a/crates/tinymist-query/src/ty/def.rs +++ b/crates/tinymist-query/src/ty/def.rs @@ -8,13 +8,14 @@ use std::{ sync::Arc, }; -use ecow::EcoVec; +use ecow::{EcoString, EcoVec}; use once_cell::sync::OnceCell; use parking_lot::{Mutex, RwLock}; use reflexo_typst::TypstFileId; use rustc_hash::{FxHashMap, FxHashSet}; +use serde::{Deserialize, Serialize}; use typst::{ - foundations::Value, + foundations::{ParamInfo, Value}, syntax::{ast, Span, SyntaxKind, SyntaxNode}, }; @@ -49,8 +50,8 @@ pub enum Ty { Builtin(BuiltinTy), /// A possible typst instance of some type. Value(Interned), - /// A field type - Field(Interned), + /// A parameter type + Param(Interned), // Combination Types /// A union type, whose negation is intersection type. @@ -120,7 +121,7 @@ impl fmt::Debug for Ty { f.write_str(")") } Ty::Let(v) => write!(f, "({v:?})"), - Ty::Field(ff) => write!(f, "{:?}: {:?}", ff.name, ff.field), + Ty::Param(ff) => write!(f, "{:?}: {:?}", ff.name, ff.ty), Ty::Var(v) => v.fmt(f), Ty::Unary(u) => write!(f, "{u:?}"), Ty::Binary(b) => write!(f, "{b:?}"), @@ -168,6 +169,39 @@ impl Ty { Ty::Builtin(BuiltinTy::Undef) } + /// Get name of the type + pub fn name(&self) -> Interned { + match self { + Ty::Var(v) => v.name.clone(), + ty => ty + .value() + .and_then(|v| Some(Interned::new_str(v.name()?))) + .unwrap_or_default(), + } + } + + /// Get span of the type + pub fn span(&self) -> Span { + fn seq(u: &[Ty]) -> Option { + u.iter().find_map(|ty| { + let sub = ty.span(); + if sub.is_detached() { + return None; + } + Some(sub) + }) + } + + match self { + Ty::Var(v) => v.def.span(), + Ty::Let(u) => seq(&u.ubs) + .or_else(|| seq(&u.lbs)) + .unwrap_or_else(Span::detached), + Ty::Union(u) => seq(u).unwrap_or_else(Span::detached), + _ => Span::detached(), + } + } + /// Get value repr of the type pub fn value(&self) -> Option { match self { @@ -437,21 +471,88 @@ impl InsTy { } } -/// A field type -#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct FieldTy { - /// The name of the field - pub name: StrRef, - /// The type of the field - pub field: Ty, +/// Describes a function parameter. +#[derive( + Debug, Clone, Copy, Hash, Serialize, Deserialize, Default, PartialEq, Eq, PartialOrd, Ord, +)] +pub struct ParamAttrs { + /// Is the parameter positional? + pub positional: bool, + /// Is the parameter named? + /// + /// Can be true even if `positional` is true if the parameter can be given + /// in both variants. + pub named: bool, + /// Can the parameter be given any number of times? + pub variadic: bool, + /// Is the parameter settable with a set rule? + pub settable: bool, } -impl FieldTy { +impl ParamAttrs { + pub(crate) fn positional() -> ParamAttrs { + ParamAttrs { + positional: true, + named: false, + variadic: false, + settable: false, + } + } + + pub(crate) fn named() -> ParamAttrs { + ParamAttrs { + positional: false, + named: true, + variadic: false, + settable: false, + } + } + + pub(crate) fn variadic() -> ParamAttrs { + ParamAttrs { + positional: true, + named: false, + variadic: true, + settable: false, + } + } +} + +impl From<&ParamInfo> for ParamAttrs { + fn from(param: &ParamInfo) -> Self { + ParamAttrs { + positional: param.positional, + named: param.named, + variadic: param.variadic, + settable: param.settable, + } + } +} + +/// Describes a parameter type. +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct ParamTy { + /// The name of the parameter. + pub name: StrRef, + /// The docstring of the parameter. + pub docs: Option, + /// The default value of the variable + pub default: Option, + /// The type of the parameter. + pub ty: Ty, + /// The attributes of the parameter. + pub attrs: ParamAttrs, +} + +impl ParamTy { /// Create an untyped field type - pub fn new_untyped(name: StrRef) -> Interned { + pub fn new_untyped(name: StrRef, attrs: ParamAttrs) -> Interned { Interned::new(Self { name, - field: Ty::Any, + ty: Ty::Any, + docs: None, + default: None, + attrs, }) } } @@ -1163,7 +1264,7 @@ pub(super) struct TypeCanoStore { impl_internable!(Ty,); impl_internable!(InsTy,); -impl_internable!(FieldTy,); +impl_internable!(ParamTy,); impl_internable!(TypeSource,); impl_internable!(TypeVar,); impl_internable!(SigWithTy,); diff --git a/crates/tinymist-query/src/ty/describe.rs b/crates/tinymist-query/src/ty/describe.rs index 1f7e14cb..ff8be1fb 100644 --- a/crates/tinymist-query/src/ty/describe.rs +++ b/crates/tinymist-query/src/ty/describe.rs @@ -199,8 +199,8 @@ impl TypeDescriber { Ty::Value(v) if self.value => return truncated_repr_::<181>(&v.val), Ty::Value(v) if self.repr => return v.val.ty().short_name().into(), Ty::Value(v) => return v.val.repr(), - Ty::Field(..) => { - return "field".into(); + Ty::Param(..) => { + return "param".into(); } Ty::Args(..) => { return "arguments".into(); diff --git a/crates/tinymist-query/src/ty/iface.rs b/crates/tinymist-query/src/ty/iface.rs index cac3ceed..ec624949 100644 --- a/crates/tinymist-query/src/ty/iface.rs +++ b/crates/tinymist-query/src/ty/iface.rs @@ -27,8 +27,6 @@ pub enum Iface<'a> { val: &'a Module, at: &'a Ty, }, - ArrayCons(&'a TyRef), - Partialize(&'a Iface<'a>), } impl<'a> Iface<'a> { @@ -38,11 +36,9 @@ impl<'a> Iface<'a> { match self { // Iface::ArrayCons(a) => SigTy::array_cons(a.as_ref().clone(), false), - Iface::ArrayCons(..) => None, Iface::Dict(d) => d.field_by_name(key).cloned(), // Iface::Type { val, .. } => ctx?.type_of_func(&val.constructor().ok()?)?, // Iface::Value { val, .. } => ctx?.type_of_func(val)?, // todo - Iface::Partialize(..) => None, Iface::Element { .. } => None, Iface::Type { .. } => None, Iface::Value { val, at: _ } => ctx.type_of_dict(val).field_by_name(key).cloned(), diff --git a/crates/tinymist-query/src/ty/mutate.rs b/crates/tinymist-query/src/ty/mutate.rs index 86d30809..d0e03406 100644 --- a/crates/tinymist-query/src/ty/mutate.rs +++ b/crates/tinymist-query/src/ty/mutate.rs @@ -16,7 +16,7 @@ pub trait TyMutator { Func(f) => Some(Func(self.mutate_func(f, pol)?.into())), Args(args) => Some(Args(self.mutate_func(args, pol)?.into())), Pattern(args) => Some(Pattern(self.mutate_func(args, pol)?.into())), - Field(f) => Some(Field(self.mutate_field(f, pol)?.into())), + Param(f) => Some(Param(self.mutate_field(f, pol)?.into())), Select(s) => Some(Select(self.mutate_select(s, pol)?.into())), With(w) => Some(With(self.mutate_with_sig(w, pol)?.into())), Unary(u) => Some(Unary(self.mutate_unary(u, pol)?.into())), @@ -71,10 +71,10 @@ pub trait TyMutator { }) } - fn mutate_field(&mut self, f: &Interned, pol: bool) -> Option { - let field = self.mutate(&f.field, pol)?; + fn mutate_field(&mut self, f: &Interned, pol: bool) -> Option { + let ty = self.mutate(&f.ty, pol)?; let mut f = f.as_ref().clone(); - f.field = field; + f.ty = ty; Some(f) } diff --git a/crates/tinymist-query/src/ty/sig.rs b/crates/tinymist-query/src/ty/sig.rs index d0225b31..1d54dc84 100644 --- a/crates/tinymist-query/src/ty/sig.rs +++ b/crates/tinymist-query/src/ty/sig.rs @@ -237,6 +237,10 @@ impl<'a> SigCheckDriver<'a> { Ty::Unary(_) => {} Ty::Binary(_) => {} Ty::If(_) => {} + Ty::Param(p) => { + // todo: keep type information + self.ty(&p.ty, pol); + } _ if ty.has_bounds() => ty.bounds(pol, self), _ => {} } diff --git a/crates/tinymist-query/src/ty/simplify.rs b/crates/tinymist-query/src/ty/simplify.rs index 42412421..dc97600d 100644 --- a/crates/tinymist-query/src/ty/simplify.rs +++ b/crates/tinymist-query/src/ty/simplify.rs @@ -152,8 +152,8 @@ impl<'a, 'b> TypeSimplifier<'a, 'b> { self.analyze(ub, pol); } } - Ty::Field(v) => { - self.analyze(&v.field, pol); + Ty::Param(v) => { + self.analyze(&v.ty, pol); } Ty::Value(_v) => {} Ty::Any => {} @@ -225,11 +225,11 @@ impl<'a, 'b> TypeSimplifier<'a, 'b> { let seq = seq_no_any.collect::>(); Ty::from_types(seq.into_iter()) } - Ty::Field(ty) => { + Ty::Param(ty) => { let mut ty = ty.as_ref().clone(); - ty.field = self.transform(&ty.field, pol); + ty.ty = self.transform(&ty.ty, pol); - Ty::Field(ty.into()) + Ty::Param(ty.into()) } Ty::Select(sel) => { let mut sel = sel.as_ref().clone(); diff --git a/crates/tinymist-query/src/upstream/complete/ext.rs b/crates/tinymist-query/src/upstream/complete/ext.rs index e62eb2b7..fcd39605 100644 --- a/crates/tinymist-query/src/upstream/complete/ext.rs +++ b/crates/tinymist-query/src/upstream/complete/ext.rs @@ -717,7 +717,7 @@ fn type_completion( ctx.snippet_completion("false", "false", "No / Disabled."); ctx.snippet_completion("true", "true", "Yes / Enabled."); } - Ty::Field(f) => { + Ty::Param(f) => { let f = &f.name; if ctx.seen_field(f.clone()) { return Some(());