dev: remove some interned uses (#279)

This commit is contained in:
Myriad-Dreamin 2024-05-13 21:04:10 +08:00 committed by GitHub
parent 6b9bd73d8a
commit f66d50c51f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 193 additions and 149 deletions

View file

@ -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) {

View file

@ -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(

View file

@ -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,

View file

@ -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);

View file

@ -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();

View file

@ -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(())

View file

@ -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> {

View file

@ -10,7 +10,7 @@
mod adt;
pub mod analysis;
pub mod syntax;
mod ty;
pub mod ty;
mod upstream;
pub(crate) mod diagnostics;

View file

@ -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,

View file

@ -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),
))
)

View file

@ -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")]"###);

View file

@ -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;
}

View file

@ -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()
}
}

View file

@ -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, &param.into(), ty.as_ref());
return true;
}
}

View file

@ -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());
}
}
}