mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-23 20:55:02 +00:00
dev: remove some interned uses (#279)
This commit is contained in:
parent
6b9bd73d8a
commit
f66d50c51f
15 changed files with 193 additions and 149 deletions
|
@ -27,6 +27,7 @@ use ecow::EcoString;
|
|||
use fxhash::FxHasher;
|
||||
use hashbrown::{hash_map::RawEntryMut, HashMap};
|
||||
use triomphe::Arc;
|
||||
use typst::{foundations::Str, syntax::ast::Ident};
|
||||
|
||||
type InternMap<T> = DashMap<Arc<T>, (), BuildHasherDefault<FxHasher>>;
|
||||
type Guard<T> = dashmap::RwLockWriteGuard<
|
||||
|
@ -98,17 +99,48 @@ impl From<&str> for Interned<str> {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Str> for Interned<str> {
|
||||
fn from(s: Str) -> Self {
|
||||
Interned::new_str(&s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<EcoString> for Interned<str> {
|
||||
fn from(s: EcoString) -> Self {
|
||||
Interned::new_str(&s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&EcoString> for Interned<str> {
|
||||
fn from(s: &EcoString) -> Self {
|
||||
Interned::new_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Ident<'_>> for Interned<str> {
|
||||
fn from(s: Ident<'_>) -> Self {
|
||||
Interned::new_str(s.get())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Interned<str>> for EcoString {
|
||||
fn from(s: &Interned<str>) -> Self {
|
||||
s.as_ref().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Internable> From<T> for Interned<T> {
|
||||
fn from(s: T) -> Self {
|
||||
Interned::new(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Internable + Clone> From<&T> for Interned<T> {
|
||||
fn from(s: &T) -> Self {
|
||||
Interned::new(s.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Internable + ?Sized> Interned<T> {
|
||||
#[inline]
|
||||
fn select(obj: &T) -> (Guard<T>, u64) {
|
||||
|
|
|
@ -4,7 +4,6 @@ use typst::syntax::SyntaxNode;
|
|||
|
||||
use super::{ParamSpec, Signature};
|
||||
use crate::{
|
||||
adt::interner::Interned,
|
||||
analysis::{analyze_signature, PrimarySignature, SignatureTarget},
|
||||
prelude::*,
|
||||
};
|
||||
|
@ -211,7 +210,7 @@ pub fn analyze_call_no_cache(
|
|||
|
||||
match arg {
|
||||
ast::Arg::Named(named) => {
|
||||
let n = Interned::new_str(named.name().as_str());
|
||||
let n = named.name().get().into();
|
||||
|
||||
if let Some(param) = signature.primary().named.get(&n) {
|
||||
info.arg_mapping.insert(
|
||||
|
|
|
@ -58,7 +58,7 @@ pub struct ParamSpec {
|
|||
impl ParamSpec {
|
||||
fn from_static(f: &Func, p: &ParamInfo) -> Arc<Self> {
|
||||
Arc::new(Self {
|
||||
name: Interned::new_str(p.name),
|
||||
name: p.name.into(),
|
||||
docs: Cow::Borrowed(p.docs),
|
||||
input: p.input.clone(),
|
||||
base_type: Ty::from_param_site(f, p, &p.input),
|
||||
|
@ -366,7 +366,7 @@ fn analyze_dyn_signature_inner(func: Func) -> Arc<PrimarySignature> {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
named.insert(Interned::new_str(param.name.as_ref()), param.clone());
|
||||
named.insert(param.name.clone(), param.clone());
|
||||
}
|
||||
|
||||
if param.variadic {
|
||||
|
@ -400,7 +400,7 @@ fn analyze_dyn_signature_inner(func: Func) -> Arc<PrimarySignature> {
|
|||
rest,
|
||||
ret_ty,
|
||||
has_fill_or_size_or_stroke: has_fill || has_stroke || has_size,
|
||||
sig_ty: Interned::new(sig_ty),
|
||||
sig_ty: sig_ty.into(),
|
||||
_broken: broken,
|
||||
})
|
||||
}
|
||||
|
@ -420,7 +420,7 @@ fn analyze_closure_signature(c: Arc<LazyHash<Closure>>) -> Vec<Arc<ParamSpec>> {
|
|||
match param {
|
||||
ast::Param::Pos(ast::Pattern::Placeholder(..)) => {
|
||||
params.push(Arc::new(ParamSpec {
|
||||
name: Interned::new_str("_"),
|
||||
name: "_".into(),
|
||||
input: CastInfo::Any,
|
||||
base_type: None,
|
||||
type_repr: None,
|
||||
|
@ -442,7 +442,7 @@ fn analyze_closure_signature(c: Arc<LazyHash<Closure>>) -> Vec<Arc<ParamSpec>> {
|
|||
let name = name[0].as_str();
|
||||
|
||||
params.push(Arc::new(ParamSpec {
|
||||
name: Interned::new_str(name),
|
||||
name: name.into(),
|
||||
input: CastInfo::Any,
|
||||
base_type: None,
|
||||
type_repr: None,
|
||||
|
@ -459,7 +459,7 @@ fn analyze_closure_signature(c: Arc<LazyHash<Closure>>) -> Vec<Arc<ParamSpec>> {
|
|||
ast::Param::Named(n) => {
|
||||
let expr = unwrap_expr(n.expr()).to_untyped().clone().into_text();
|
||||
params.push(Arc::new(ParamSpec {
|
||||
name: Interned::new_str(n.name().as_str()),
|
||||
name: n.name().into(),
|
||||
input: CastInfo::Any,
|
||||
base_type: None,
|
||||
type_repr: Some(expr.clone()),
|
||||
|
@ -475,7 +475,7 @@ fn analyze_closure_signature(c: Arc<LazyHash<Closure>>) -> Vec<Arc<ParamSpec>> {
|
|||
ast::Param::Spread(n) => {
|
||||
let ident = n.sink_ident().map(|e| e.as_str());
|
||||
params.push(Arc::new(ParamSpec {
|
||||
name: Interned::new_str(ident.unwrap_or_default()),
|
||||
name: ident.unwrap_or_default().into(),
|
||||
input: CastInfo::Any,
|
||||
base_type: None,
|
||||
type_repr: None,
|
||||
|
|
|
@ -13,7 +13,7 @@ use typst::{
|
|||
};
|
||||
|
||||
use crate::analysis::{Ty, *};
|
||||
use crate::{adt::interner::Interned, analysis::TypeCheckInfo, ty::TypeInterace, AnalysisContext};
|
||||
use crate::{analysis::TypeCheckInfo, ty::TypeInterace, AnalysisContext};
|
||||
|
||||
use super::{
|
||||
resolve_global_value, BuiltinTy, DefUseInfo, FlowVarKind, IdentRef, TypeBounds, TypeVar,
|
||||
|
@ -96,7 +96,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
def_id,
|
||||
TypeVarBounds::new(
|
||||
TypeVar {
|
||||
name: Interned::new_str(&r.name),
|
||||
name: r.name.as_str().into(),
|
||||
def: def_id,
|
||||
syntax: None,
|
||||
},
|
||||
|
@ -307,17 +307,11 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
let rhs = if expected_in {
|
||||
match container {
|
||||
Ty::Tuple(elements) => Ty::Union(elements.clone()),
|
||||
_ => Ty::Unary(Interned::new(TypeUnary {
|
||||
op: UnaryOp::ElementOf,
|
||||
lhs: Interned::new(container.clone()),
|
||||
})),
|
||||
_ => Ty::Unary(TypeUnary::new(UnaryOp::ElementOf, container.into())),
|
||||
}
|
||||
} else {
|
||||
Ty::Unary(Interned::new(TypeUnary {
|
||||
// todo: remove not element of
|
||||
op: UnaryOp::NotElementOf,
|
||||
lhs: Interned::new(container.clone()),
|
||||
}))
|
||||
// todo: remove not element of
|
||||
Ty::Unary(TypeUnary::new(UnaryOp::NotElementOf, container.into()))
|
||||
};
|
||||
|
||||
self.constrain(elem, &rhs);
|
||||
|
|
|
@ -45,10 +45,8 @@ impl<'a, 'b, 'w> ApplyChecker for ApplyTypeChecker<'a, 'b, 'w> {
|
|||
if let Sig::TypeCons { val, .. } = sig {
|
||||
if *val == typst::foundations::Type::of::<typst::foundations::Type>() {
|
||||
if let Some(p0) = args.pos(0) {
|
||||
self.resultant.push(Ty::Unary(Interned::new(TypeUnary {
|
||||
op: UnaryOp::TypeOf,
|
||||
lhs: Interned::new(p0.clone()),
|
||||
})));
|
||||
self.resultant
|
||||
.push(Ty::Unary(TypeUnary::new(UnaryOp::TypeOf, p0.into())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,10 +78,8 @@ impl<'a, 'b, 'w> ApplyChecker for ApplyTypeChecker<'a, 'b, 'w> {
|
|||
log::warn!("Partialize is not implemented yet {sig:?}");
|
||||
return;
|
||||
};
|
||||
self.resultant.push(Ty::With(Interned::new(SigWithTy {
|
||||
sig: Interned::new(sig),
|
||||
with: args.clone(),
|
||||
})));
|
||||
self.resultant
|
||||
.push(Ty::With(SigWithTy::new(sig.into(), args.clone())));
|
||||
}
|
||||
|
||||
// let f = v.as_ref();
|
||||
|
|
|
@ -53,7 +53,7 @@ impl SignatureReceiver {
|
|||
}
|
||||
|
||||
fn finalize(self) -> Ty {
|
||||
Ty::Let(Interned::new(self.bounds))
|
||||
Ty::Let(self.bounds.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ fn check_signature<'a>(
|
|||
match &target {
|
||||
ParamTarget::Named(n) => {
|
||||
let ident = n.cast::<ast::Ident>()?;
|
||||
let ty = sig_ins.named(&Interned::new_str(ident.get()))?;
|
||||
let ty = sig_ins.named(&ident.into())?;
|
||||
receiver.insert(ty, !pol);
|
||||
|
||||
Some(())
|
||||
|
|
|
@ -208,7 +208,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
elements.push(ty);
|
||||
}
|
||||
|
||||
Some(Ty::Tuple(Interned::new(elements)))
|
||||
Some(Ty::Tuple(elements.into()))
|
||||
}
|
||||
|
||||
fn check_dict(&mut self, root: LinkedNode<'_>) -> Option<Ty> {
|
||||
|
@ -219,7 +219,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
for field in dict.items() {
|
||||
match field {
|
||||
ast::DictItem::Named(n) => {
|
||||
let name = Interned::new_str(n.name().get());
|
||||
let name = n.name().into();
|
||||
let value = self.check_expr_in(n.expr().span(), root.clone());
|
||||
fields.push((name, value, n.span()));
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
let key = self.ctx.const_eval(k.key());
|
||||
if let Some(Value::Str(key)) = key {
|
||||
let value = self.check_expr_in(k.expr().span(), root.clone());
|
||||
fields.push((Interned::new_str(&key), value, k.span()));
|
||||
fields.push((key.into(), value, k.span()));
|
||||
}
|
||||
}
|
||||
// todo: var dict union
|
||||
|
@ -247,14 +247,14 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
|
||||
let op = unary.op();
|
||||
|
||||
let lhs = Interned::new(self.check_expr_in(unary.expr().span(), root));
|
||||
let lhs = self.check_expr_in(unary.expr().span(), root).into();
|
||||
let op = match op {
|
||||
ast::UnOp::Pos => UnaryOp::Pos,
|
||||
ast::UnOp::Neg => UnaryOp::Neg,
|
||||
ast::UnOp::Not => UnaryOp::Not,
|
||||
};
|
||||
|
||||
Some(Ty::Unary(Interned::new(TypeUnary { op, lhs })))
|
||||
Some(Ty::Unary(TypeUnary::new(op, lhs)))
|
||||
}
|
||||
|
||||
fn check_binary(&mut self, root: LinkedNode<'_>) -> Option<Ty> {
|
||||
|
@ -299,10 +299,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
}
|
||||
}
|
||||
|
||||
let res = Ty::Binary(Interned::new(TypeBinary {
|
||||
op,
|
||||
operands: Interned::new((lhs, rhs)),
|
||||
}));
|
||||
let res = Ty::Binary(TypeBinary::new(op, lhs.into(), rhs.into()));
|
||||
|
||||
Some(res)
|
||||
}
|
||||
|
@ -313,10 +310,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
let ty = self.check_expr_in(field_access.target().span(), root.clone());
|
||||
let field = field_access.field().get().clone();
|
||||
|
||||
Some(Ty::Select(Interned::new(SelectTy {
|
||||
ty: Interned::new(ty),
|
||||
select: Interned::new_str(&field),
|
||||
})))
|
||||
Some(Ty::Select(SelectTy::new(ty.into(), field.into())))
|
||||
}
|
||||
|
||||
fn check_func_call(&mut self, root: LinkedNode<'_>) -> Option<Ty> {
|
||||
|
@ -353,9 +347,8 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
args_res.push(self.check_expr_in(e.span(), root.clone()));
|
||||
}
|
||||
ast::Arg::Named(n) => {
|
||||
let name = Interned::new_str(n.name().get());
|
||||
let value = self.check_expr_in(n.expr().span(), root.clone());
|
||||
named.push((name, value));
|
||||
named.push((n.name().into(), value));
|
||||
}
|
||||
// todo
|
||||
ast::Arg::Spread(_w) => {}
|
||||
|
@ -364,7 +357,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
|
||||
let args = ArgsTy::new(args_res.into_iter(), named.into_iter(), None, None);
|
||||
|
||||
Some(Ty::Args(Interned::new(args)))
|
||||
Some(Ty::Args(args.into()))
|
||||
}
|
||||
|
||||
fn check_closure(&mut self, root: LinkedNode<'_>) -> Option<Ty> {
|
||||
|
@ -385,7 +378,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
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(Interned::new_str(e.name().get()), v.as_type());
|
||||
named.insert(e.name().into(), v.as_type());
|
||||
}
|
||||
// todo: spread left/right
|
||||
ast::Param::Spread(a) => {
|
||||
|
@ -416,7 +409,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
}
|
||||
|
||||
let sig = SigTy::new(pos.into_iter(), named.into_iter(), rest, Some(body));
|
||||
Some(Ty::Func(Interned::new(sig)))
|
||||
Some(Ty::Func(sig.into()))
|
||||
}
|
||||
|
||||
fn check_let(&mut self, root: LinkedNode<'_>) -> Option<Ty> {
|
||||
|
@ -493,10 +486,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
|
||||
let body = self.check_expr_in(contextual.body().span(), root);
|
||||
|
||||
Some(Ty::Unary(Interned::new(TypeUnary {
|
||||
op: UnaryOp::Context,
|
||||
lhs: Interned::new(body),
|
||||
})))
|
||||
Some(Ty::Unary(TypeUnary::new(UnaryOp::Context, body.into())))
|
||||
}
|
||||
|
||||
fn check_conditional(&mut self, root: LinkedNode<'_>) -> Option<Ty> {
|
||||
|
@ -509,10 +499,7 @@ impl<'a, 'w> TypeChecker<'a, 'w> {
|
|||
.map(|else_body| self.check_expr_in(else_body.span(), root.clone()))
|
||||
.unwrap_or(Ty::None);
|
||||
|
||||
let cond = Interned::new(cond);
|
||||
let then = Interned::new(then);
|
||||
let else_ = Interned::new(else_);
|
||||
Some(Ty::If(Interned::new(IfTy { cond, then, else_ })))
|
||||
Some(Ty::If(IfTy::new(cond.into(), then.into(), else_.into())))
|
||||
}
|
||||
|
||||
fn check_while_loop(&mut self, root: LinkedNode<'_>) -> Option<Ty> {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
mod adt;
|
||||
pub mod analysis;
|
||||
pub mod syntax;
|
||||
mod ty;
|
||||
pub mod ty;
|
||||
mod upstream;
|
||||
|
||||
pub(crate) mod diagnostics;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::{adt::interner::Interned, ty::def::*};
|
||||
|
||||
use super::{Sig, SigChecker, SigSurfaceKind};
|
||||
|
@ -15,12 +17,12 @@ impl Ty {
|
|||
self.apply(SigSurfaceKind::Call, args, pol, checker)
|
||||
}
|
||||
|
||||
// pub fn element_of(&self, pol: bool, checker: &mut impl ApplyChecker) {
|
||||
// static EMPTY_ARGS: Lazy<Interned<ArgsTy>> =
|
||||
// Lazy::new(|| Interned::new(ArgsTy::default()));
|
||||
#[allow(dead_code)]
|
||||
pub fn element_of(&self, pol: bool, checker: &mut impl ApplyChecker) {
|
||||
static EMPTY_ARGS: Lazy<Interned<ArgsTy>> = Lazy::new(|| ArgsTy::default().into());
|
||||
|
||||
// self.apply(SigSurfaceKind::ArrayOrDict, &EMPTY_ARGS, pol, checker)
|
||||
// }
|
||||
self.apply(SigSurfaceKind::ArrayOrDict, &EMPTY_ARGS, pol, checker)
|
||||
}
|
||||
|
||||
fn apply(
|
||||
&self,
|
||||
|
|
|
@ -101,9 +101,7 @@ impl Ty {
|
|||
// flat union
|
||||
let e = UnionIter(vec![e.as_slice().iter()]);
|
||||
|
||||
Ty::Union(Interned::new(
|
||||
e.flat_map(|e| Self::from_return_site(f, e)).collect(),
|
||||
))
|
||||
Ty::iter_union(e.flat_map(|e| Self::from_return_site(f, e)))
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -130,9 +128,7 @@ impl Ty {
|
|||
// flat union
|
||||
let e = UnionIter(vec![e.as_slice().iter()]);
|
||||
|
||||
Ty::Union(Interned::new(
|
||||
e.flat_map(|e| Self::from_param_site(f, p, e)).collect(),
|
||||
))
|
||||
Ty::iter_union(e.flat_map(|e| Self::from_param_site(f, p, e)))
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -324,7 +320,7 @@ macro_rules! flow_builtin_union_inner {
|
|||
macro_rules! flow_union {
|
||||
// the first one is string
|
||||
($($b:tt)*) => {
|
||||
Ty::Union(Interned::new(flow_builtin_union_inner!( $($b)* )))
|
||||
Ty::iter_union(flow_builtin_union_inner!( $($b)* ).into_iter())
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -359,10 +355,7 @@ pub(super) fn param_mapping(f: &Func, p: &ParamInfo) -> Option<Ty> {
|
|||
("text", "size") => Some(literally(TextSize)),
|
||||
("text", "font") => {
|
||||
static FONT_TYPE: Lazy<Ty> = Lazy::new(|| {
|
||||
Ty::Union(Interned::new(vec![
|
||||
literally(TextFont),
|
||||
Ty::Array(Interned::new(literally(TextFont))),
|
||||
]))
|
||||
Ty::iter_union([literally(TextFont), Ty::Array(literally(TextFont).into())])
|
||||
});
|
||||
Some(FONT_TYPE.clone())
|
||||
}
|
||||
|
@ -390,7 +383,7 @@ pub(super) fn param_mapping(f: &Func, p: &ParamInfo) -> Option<Ty> {
|
|||
Ty::Value(InsTy::new(Value::Auto)),
|
||||
Ty::Value(InsTy::new(Value::Type(Type::of::<i64>()))),
|
||||
literally(Length),
|
||||
Ty::Array(Interned::new(literally(Length))),
|
||||
Ty::Array(literally(Length).into()),
|
||||
)
|
||||
});
|
||||
Some(COLUMN_TYPE.clone())
|
||||
|
@ -399,7 +392,7 @@ pub(super) fn param_mapping(f: &Func, p: &ParamInfo) -> Option<Ty> {
|
|||
static PATTERN_SIZE_TYPE: Lazy<Ty> = Lazy::new(|| {
|
||||
flow_union!(
|
||||
Ty::Value(InsTy::new(Value::Auto)),
|
||||
Ty::Array(Interned::new(Ty::Builtin(Length))),
|
||||
Ty::Array(Ty::Builtin(Length).into()),
|
||||
)
|
||||
});
|
||||
Some(PATTERN_SIZE_TYPE.clone())
|
||||
|
@ -429,9 +422,9 @@ static FLOW_STROKE_DASH_TYPE: Lazy<Ty> = Lazy::new(|| {
|
|||
"dash-dotted",
|
||||
"densely-dash-dotted",
|
||||
"loosely-dash-dotted",
|
||||
Ty::Array(Interned::new(flow_union!("dot", literally(Float)))),
|
||||
Ty::Array(flow_union!("dot", literally(Float)).into()),
|
||||
Ty::Dict(flow_record!(
|
||||
"array" => Ty::Array(Interned::new(flow_union!("dot", literally(Float)))),
|
||||
"array" => Ty::Array(flow_union!("dot", literally(Float)).into()),
|
||||
"phase" => literally(Length),
|
||||
))
|
||||
)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(unused)]
|
||||
|
||||
use core::fmt;
|
||||
use ecow::{EcoString, EcoVec};
|
||||
use ecow::EcoVec;
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use reflexo::vector::ir::DefId;
|
||||
|
@ -99,10 +99,10 @@ impl TypeSource {
|
|||
.get_or_init(|| {
|
||||
let name = self.name_node.text();
|
||||
if !name.is_empty() {
|
||||
return Interned::new_str(name.as_str());
|
||||
return name.into();
|
||||
}
|
||||
let name = self.name_node.clone().into_text();
|
||||
Interned::new_str(name.as_str())
|
||||
name.into()
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ impl Eq for InsTy {}
|
|||
|
||||
impl InsTy {
|
||||
pub fn new(val: Value) -> Interned<Self> {
|
||||
Interned::new(Self { val, syntax: None })
|
||||
Self { val, syntax: None }.into()
|
||||
}
|
||||
pub fn new_at(val: Value, s: Span) -> Interned<Self> {
|
||||
Interned::new(Self {
|
||||
|
@ -145,7 +145,7 @@ impl InsTy {
|
|||
name_node: SyntaxNode::default(),
|
||||
name_repr: OnceCell::new(),
|
||||
span: s,
|
||||
doc: Interned::new_str(""),
|
||||
doc: "".into(),
|
||||
})),
|
||||
})
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ impl InsTy {
|
|||
name_node: SyntaxNode::default(),
|
||||
name_repr: OnceCell::new(),
|
||||
span: Span::detached(),
|
||||
doc: Interned::new_str(doc),
|
||||
doc: doc.into(),
|
||||
})),
|
||||
})
|
||||
}
|
||||
|
@ -637,6 +637,12 @@ pub struct SigWithTy {
|
|||
pub with: Interned<ArgsTy>,
|
||||
}
|
||||
|
||||
impl SigWithTy {
|
||||
pub fn new(sig: TyRef, with: Interned<ArgsTy>) -> Interned<Self> {
|
||||
Interned::new(Self { sig, with })
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for SigWithTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}.with({:?})", self.sig, self.with)
|
||||
|
@ -649,6 +655,12 @@ pub struct SelectTy {
|
|||
pub select: Interned<str>,
|
||||
}
|
||||
|
||||
impl SelectTy {
|
||||
pub fn new(ty: Interned<Ty>, select: Interned<str>) -> Interned<Self> {
|
||||
Interned::new(Self { ty, select })
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for SelectTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}.{}", RefDebug(&self.ty), self.select)
|
||||
|
@ -672,15 +684,28 @@ pub struct TypeUnary {
|
|||
pub op: UnaryOp,
|
||||
}
|
||||
|
||||
impl TypeUnary {
|
||||
pub fn new(op: UnaryOp, lhs: Interned<Ty>) -> Interned<Self> {
|
||||
Interned::new(Self { lhs, op })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Hash, Clone, PartialEq, Eq)]
|
||||
pub struct TypeBinary {
|
||||
pub operands: Interned<(Ty, Ty)>,
|
||||
pub operands: (Interned<Ty>, Interned<Ty>),
|
||||
pub op: ast::BinOp,
|
||||
}
|
||||
|
||||
impl TypeBinary {
|
||||
pub fn repr(&self) -> &(Ty, Ty) {
|
||||
&self.operands
|
||||
pub fn new(op: ast::BinOp, lhs: Interned<Ty>, rhs: Interned<Ty>) -> Interned<Self> {
|
||||
Interned::new(Self {
|
||||
operands: (lhs, rhs),
|
||||
op,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn repr(&self) -> (&Interned<Ty>, &Interned<Ty>) {
|
||||
(&self.operands.0, &self.operands.1)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -691,6 +716,12 @@ pub(crate) struct IfTy {
|
|||
pub else_: Interned<Ty>,
|
||||
}
|
||||
|
||||
impl IfTy {
|
||||
pub fn new(cond: Interned<Ty>, then: Interned<Ty>, else_: Interned<Ty>) -> Interned<Self> {
|
||||
Interned::new(Self { cond, then, else_ })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Hash, Clone, PartialEq, Eq)]
|
||||
pub(crate) enum Ty {
|
||||
Clause,
|
||||
|
@ -790,9 +821,13 @@ impl Ty {
|
|||
let mut e = e;
|
||||
e.next().unwrap()
|
||||
} else {
|
||||
Ty::Union(Interned::new(e.collect()))
|
||||
Self::iter_union(e)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn iter_union(e: impl IntoIterator<Item = Ty>) -> Self {
|
||||
Ty::Union(Interned::new(e.into_iter().collect()))
|
||||
}
|
||||
}
|
||||
|
||||
impl_internable!(Ty,);
|
||||
|
@ -831,6 +866,8 @@ fn interpersed<T: fmt::Debug>(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use insta::{assert_debug_snapshot, assert_snapshot};
|
||||
|
||||
use crate::ty::tests::*;
|
||||
#[test]
|
||||
fn test_ty() {
|
||||
use super::*;
|
||||
|
@ -843,25 +880,6 @@ mod tests {
|
|||
fn test_sig_matches() {
|
||||
use super::*;
|
||||
|
||||
fn str_ins(s: &str) -> Ty {
|
||||
Ty::Value(InsTy::new(Value::Str(s.into())))
|
||||
}
|
||||
|
||||
fn str_sig(
|
||||
pos: &[&str],
|
||||
named: &[(&str, &str)],
|
||||
rest: Option<&str>,
|
||||
ret: Option<&str>,
|
||||
) -> Interned<SigTy> {
|
||||
let pos = pos.iter().map(|s| str_ins(s));
|
||||
let named = named
|
||||
.iter()
|
||||
.map(|(n, t)| (Interned::new_str(n), str_ins(t)));
|
||||
let rest = rest.map(str_ins);
|
||||
let ret = ret.map(str_ins);
|
||||
Interned::new(SigTy::new(pos, named, rest, ret))
|
||||
}
|
||||
|
||||
fn matches(
|
||||
sig: Interned<SigTy>,
|
||||
args: Interned<SigTy>,
|
||||
|
@ -871,22 +889,6 @@ mod tests {
|
|||
format!("{res:?}")
|
||||
}
|
||||
|
||||
// args*, (keys: values)*, ...rest -> ret
|
||||
macro_rules! literal_sig {
|
||||
($($pos:ident),* $(!$named:ident: $named_ty:ident),* $(,)? ...$rest:ident -> $ret:ident) => {
|
||||
str_sig(&[$(stringify!($pos)),*], &[$((stringify!($named), stringify!($named_ty))),*], Some(stringify!($rest)), Some(stringify!($ret)))
|
||||
};
|
||||
($($pos:ident),* $(!$named:ident: $named_ty:ident),* $(,)? -> $ret:ident) => {
|
||||
str_sig(&[$(stringify!($pos)),*], &[$((stringify!($named), stringify!($named_ty))),*], None, Some(stringify!($ret)))
|
||||
};
|
||||
($($pos:ident),* $(!$named:ident: $named_ty:ident),* $(,)? ...$rest:ident) => {
|
||||
str_sig(&[$(stringify!($pos)),*], &[$((stringify!($named), stringify!($named_ty))),*], Some(stringify!($rest)), None)
|
||||
};
|
||||
($($pos:ident),* $(!$named:ident: $named_ty:ident),* $(,)?) => {
|
||||
str_sig(&[$(stringify!($pos)),*], &[$((stringify!($named), stringify!($named_ty))),*], None, None)
|
||||
};
|
||||
}
|
||||
|
||||
assert_snapshot!(matches(literal_sig!(p1), literal_sig!(q1), None), @r###"[("p1", "q1")]"###);
|
||||
assert_snapshot!(matches(literal_sig!(p1, p2), literal_sig!(q1), None), @r###"[("p1", "q1")]"###);
|
||||
assert_snapshot!(matches(literal_sig!(p1, p2), literal_sig!(q1, q2), None), @r###"[("p1", "q1"), ("p2", "q2")]"###);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Types and type operations for Typst.
|
||||
|
||||
mod apply;
|
||||
mod bound;
|
||||
mod builtin;
|
||||
|
@ -12,3 +14,45 @@ pub(crate) use bound::*;
|
|||
pub(crate) use builtin::*;
|
||||
pub(crate) use def::*;
|
||||
pub(crate) use sig::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::adt::interner::Interned;
|
||||
use typst::foundations::Value;
|
||||
|
||||
pub fn str_ins(s: &str) -> Ty {
|
||||
Ty::Value(InsTy::new(Value::Str(s.into())))
|
||||
}
|
||||
|
||||
pub fn str_sig(
|
||||
pos: &[&str],
|
||||
named: &[(&str, &str)],
|
||||
rest: Option<&str>,
|
||||
ret: Option<&str>,
|
||||
) -> Interned<SigTy> {
|
||||
let pos = pos.iter().map(|s| str_ins(s));
|
||||
let named = named.iter().map(|(n, t)| ((*n).into(), str_ins(t)));
|
||||
let rest = rest.map(str_ins);
|
||||
let ret = ret.map(str_ins);
|
||||
SigTy::new(pos, named, rest, ret).into()
|
||||
}
|
||||
|
||||
// args*, (keys: values)*, ...rest -> ret
|
||||
macro_rules! literal_sig {
|
||||
($($pos:ident),* $(!$named:ident: $named_ty:ident),* $(,)? ...$rest:ident -> $ret:ident) => {
|
||||
str_sig(&[$(stringify!($pos)),*], &[$((stringify!($named), stringify!($named_ty))),*], Some(stringify!($rest)), Some(stringify!($ret)))
|
||||
};
|
||||
($($pos:ident),* $(!$named:ident: $named_ty:ident),* $(,)? -> $ret:ident) => {
|
||||
str_sig(&[$(stringify!($pos)),*], &[$((stringify!($named), stringify!($named_ty))),*], None, Some(stringify!($ret)))
|
||||
};
|
||||
($($pos:ident),* $(!$named:ident: $named_ty:ident),* $(,)? ...$rest:ident) => {
|
||||
str_sig(&[$(stringify!($pos)),*], &[$((stringify!($named), stringify!($named_ty))),*], Some(stringify!($rest)), None)
|
||||
};
|
||||
($($pos:ident),* $(!$named:ident: $named_ty:ident),* $(,)?) => {
|
||||
str_sig(&[$(stringify!($pos)),*], &[$((stringify!($named), stringify!($named_ty))),*], None, None)
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use literal_sig;
|
||||
}
|
||||
|
|
|
@ -196,50 +196,44 @@ impl<'a, 'b> TypeSimplifier<'a, 'b> {
|
|||
let mut f = f.as_ref().clone();
|
||||
f.types = self.transform_seq(&f.types, pol);
|
||||
|
||||
Ty::Dict(Interned::new(f))
|
||||
Ty::Dict(f.into())
|
||||
}
|
||||
Ty::Tuple(e) => Ty::Tuple(self.transform_seq(e, pol)),
|
||||
Ty::Array(e) => Ty::Array(Interned::new(self.transform(e, pol))),
|
||||
Ty::Array(e) => Ty::Array(self.transform(e, pol).into()),
|
||||
Ty::With(w) => {
|
||||
let sig = Interned::new(self.transform(&w.sig, pol));
|
||||
let sig = self.transform(&w.sig, pol).into();
|
||||
// Negate the pol to make correct covariance
|
||||
let with = self.transform_sig(&w.with, !pol);
|
||||
|
||||
Ty::With(Interned::new(SigWithTy { sig, with }))
|
||||
Ty::With(SigWithTy::new(sig, with))
|
||||
}
|
||||
// Negate the pol to make correct covariance
|
||||
Ty::Args(args) => Ty::Args(self.transform_sig(args, !pol)),
|
||||
Ty::Unary(u) => Ty::Unary(Interned::new(TypeUnary {
|
||||
op: u.op,
|
||||
lhs: Interned::new(self.transform(&u.lhs, pol)),
|
||||
})),
|
||||
Ty::Unary(u) => Ty::Unary(TypeUnary::new(u.op, self.transform(&u.lhs, pol).into())),
|
||||
Ty::Binary(b) => {
|
||||
let (lhs, rhs) = b.repr();
|
||||
let lhs = self.transform(lhs, pol);
|
||||
let rhs = self.transform(rhs, pol);
|
||||
|
||||
Ty::Binary(Interned::new(TypeBinary {
|
||||
op: b.op,
|
||||
operands: Interned::new((lhs, rhs)),
|
||||
}))
|
||||
Ty::Binary(TypeBinary::new(b.op, lhs.into(), rhs.into()))
|
||||
}
|
||||
Ty::If(i) => Ty::If(Interned::new(IfTy {
|
||||
cond: Interned::new(self.transform(&i.cond, pol)),
|
||||
then: Interned::new(self.transform(&i.then, pol)),
|
||||
else_: Interned::new(self.transform(&i.else_, pol)),
|
||||
})),
|
||||
Ty::If(i) => Ty::If(IfTy::new(
|
||||
self.transform(&i.cond, pol).into(),
|
||||
self.transform(&i.then, pol).into(),
|
||||
self.transform(&i.else_, pol).into(),
|
||||
)),
|
||||
Ty::Union(v) => Ty::Union(self.transform_seq(v, pol)),
|
||||
Ty::Field(ty) => {
|
||||
let mut ty = ty.as_ref().clone();
|
||||
ty.field = self.transform(&ty.field, pol);
|
||||
|
||||
Ty::Field(Interned::new(ty))
|
||||
Ty::Field(ty.into())
|
||||
}
|
||||
Ty::Select(sel) => {
|
||||
let mut sel = sel.as_ref().clone();
|
||||
sel.ty = Interned::new(self.transform(&sel.ty, pol));
|
||||
sel.ty = self.transform(&sel.ty, pol).into();
|
||||
|
||||
Ty::Select(Interned::new(sel))
|
||||
Ty::Select(sel.into())
|
||||
}
|
||||
|
||||
Ty::Value(v) => Ty::Value(v.clone()),
|
||||
|
@ -258,7 +252,8 @@ impl<'a, 'b> TypeSimplifier<'a, 'b> {
|
|||
}
|
||||
|
||||
fn transform_seq(&mut self, seq: &[Ty], pol: bool) -> Interned<Vec<Ty>> {
|
||||
Interned::new(seq.iter().map(|ty| self.transform(ty, pol)).collect())
|
||||
let seq = seq.iter().map(|ty| self.transform(ty, pol));
|
||||
seq.collect::<Vec<_>>().into()
|
||||
}
|
||||
|
||||
// todo: reduce duplication
|
||||
|
@ -288,7 +283,7 @@ impl<'a, 'b> TypeSimplifier<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
Ty::Let(Interned::new(TypeBounds { lbs, ubs }))
|
||||
Ty::Let(TypeBounds { lbs, ubs }.into())
|
||||
}
|
||||
|
||||
fn transform_sig(&mut self, sig: &SigTy, pol: bool) -> Interned<SigTy> {
|
||||
|
@ -299,6 +294,6 @@ impl<'a, 'b> TypeSimplifier<'a, 'b> {
|
|||
}
|
||||
|
||||
// todo: we can reduce one clone by early compare on sig.types
|
||||
Interned::new(sig)
|
||||
sig.into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -722,7 +722,7 @@ fn complete_params(ctx: &mut CompletionContext) -> bool {
|
|||
let ty = ctx.ctx.type_of(param.to_untyped());
|
||||
log::debug!("named param type: {:?}", ty);
|
||||
|
||||
named_param_value_completions(ctx, callee, &Interned::new_str(param.get()), ty.as_ref());
|
||||
named_param_value_completions(ctx, callee, ¶m.into(), ty.as_ref());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -588,7 +588,7 @@ pub fn param_completions<'a>(
|
|||
|
||||
for arg in args.items() {
|
||||
if let ast::Arg::Named(named) = arg {
|
||||
ctx.seen_field(named.name().get().into());
|
||||
ctx.seen_field(named.name().into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1034,7 +1034,7 @@ pub(crate) fn complete_type(ctx: &mut CompletionContext) -> Option<()> {
|
|||
if let Some(container) = container.cast::<ast::Dict>() {
|
||||
for named in container.items() {
|
||||
if let ast::DictItem::Named(named) = named {
|
||||
ctx.seen_field(named.name().get().into());
|
||||
ctx.seen_field(named.name().into());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1043,7 +1043,7 @@ pub(crate) fn complete_type(ctx: &mut CompletionContext) -> Option<()> {
|
|||
let args = args.cast::<ast::Args>()?;
|
||||
for arg in args.items() {
|
||||
if let ast::Arg::Named(named) = arg {
|
||||
ctx.seen_field(named.name().get().into());
|
||||
ctx.seen_field(named.name().into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue