Skip to content

Commit

Permalink
perf: Avoid allocating new ArcKind in Type::kind
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Jan 27, 2019
1 parent b2e8705 commit 2911d7e
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 35 deletions.
53 changes: 27 additions & 26 deletions base/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,22 @@ use stable_deref_trait::StableDeref;

use itertools::Itertools;

use crate::ast::{Commented, EmptyEnv, IdentEnv};
use crate::fnv::FnvMap;
use crate::kind::{ArcKind, Kind, KindEnv};
use crate::merge::merge;
use crate::metadata::Comment;
use crate::pos::{BytePos, HasSpan, Span};
use crate::source::Source;
use crate::symbol::{Name, Symbol, SymbolRef};
use crate::{
ast::{Commented, EmptyEnv, IdentEnv},
fnv::FnvMap,
kind::{ArcKind, Kind, KindCache, KindEnv},
merge::merge,
metadata::Comment,
pos::{BytePos, HasSpan, Span},
source::Source,
symbol::{Name, Symbol, SymbolRef},
};

#[cfg(feature = "serde")]
use crate::serde::de::DeserializeState;
#[cfg(feature = "serde")]
use crate::serde::ser::SerializeState;
#[cfg(feature = "serde")]
use crate::serialization::{SeSeed, Seed};
use crate::{
serde::{de::DeserializeState, ser::SerializeState},
serialization::{SeSeed, Seed},
};

use self::pretty_print::Printer;
pub use self::{
Expand Down Expand Up @@ -667,8 +668,8 @@ where
&self.typ
}

pub fn kind(&self) -> Cow<ArcKind> {
let result_type = self.unresolved_type().kind();
pub fn kind<'k>(&'k self, cache: &'k KindCache) -> Cow<'k, ArcKind> {
let result_type = self.unresolved_type().kind(cache);
self.params().iter().rev().fold(result_type, |acc, param| {
Cow::Owned(Kind::function(param.kind.clone(), acc.into_owned()))
})
Expand Down Expand Up @@ -1145,16 +1146,16 @@ where
}
}

pub fn kind(&self) -> Cow<ArcKind> {
self.kind_(0)
pub fn kind<'k>(&'k self, cache: &'k KindCache) -> Cow<'k, ArcKind> {
self.kind_(cache, 0)
}

fn kind_(&self, applied_args: usize) -> Cow<ArcKind> {
fn kind_<'k>(&'k self, cache: &'k KindCache, applied_args: usize) -> Cow<'k, ArcKind> {
let mut immediate_kind = match *self {
Type::Function(_, _, _) => Cow::Owned(Kind::typ()),
Type::App(ref t, ref args) => t.kind_(args.len()),
Type::Error => Cow::Owned(Kind::error()),
Type::Hole => Cow::Owned(Kind::hole()),
Type::Function(_, _, _) => Cow::Borrowed(&cache.typ),
Type::App(ref t, ref args) => t.kind_(cache, args.len()),
Type::Error => Cow::Borrowed(&cache.error),
Type::Hole => Cow::Borrowed(&cache.hole),
Type::Opaque | Type::Builtin(_) | Type::Record(_) | Type::Variant(_) => {
Cow::Owned(Kind::typ())
}
Expand All @@ -1163,17 +1164,17 @@ where
let t = Kind::typ();
Cow::Owned(Kind::function(t.clone(), t))
}
Type::Forall(_, ref typ) => typ.kind_(applied_args),
Type::Forall(_, ref typ) => typ.kind_(cache, applied_args),
Type::Variable(ref var) => Cow::Borrowed(&var.kind),
Type::Skolem(ref skolem) => Cow::Borrowed(&skolem.kind),
Type::Generic(ref gen) => Cow::Borrowed(&gen.kind),
// FIXME can be another kind
Type::Ident(_) | Type::Projection(_) => Cow::Owned(Kind::typ()),
Type::Ident(_) | Type::Projection(_) => Cow::Owned(cache.typ()),
Type::Alias(ref alias) => {
return if alias.params().len() < applied_args {
alias.typ.kind_(applied_args - alias.params().len())
alias.typ.kind_(cache, applied_args - alias.params().len())
} else {
let mut kind = alias.typ.kind_(0).into_owned();
let mut kind = alias.typ.kind_(cache, 0).into_owned();
for arg in &alias.params()[applied_args..] {
kind = Kind::function(arg.kind.clone(), kind)
}
Expand Down
2 changes: 1 addition & 1 deletion check/src/kindcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl<'a> KindCheck<'a> {
// Errors get reported in typecheck as well so ignore them here
crate::typecheck::translate_projected_type(self.info, self.idents, &mut NullInterner, ids)
.ok()
.map(|typ| typ.kind().into_owned())
.map(|typ| typ.kind(&self.kind_cache).into_owned())
}

// Kindhecks `typ`, infering it to be of kind `Type`
Expand Down
9 changes: 5 additions & 4 deletions check/src/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,14 @@ pub(crate) struct Environment<'a> {
stack: ScopedMap<Symbol, StackBinding>,
/// Types which exist in some scope (`type Test = ... in ...`)
stack_types: ScopedMap<Symbol, (RcType, Alias<Symbol, RcType>)>,
kind_cache: KindCache,
}

impl<'a> KindEnv for Environment<'a> {
fn find_kind(&self, type_name: &SymbolRef) -> Option<ArcKind> {
self.stack_types
.get(type_name)
.map(|&(_, ref alias)| alias.kind().into_owned())
.map(|&(_, ref alias)| alias.kind(&self.kind_cache).into_owned())
.or_else(|| self.environment.find_kind(type_name))
}
}
Expand Down Expand Up @@ -148,19 +149,19 @@ impl<'a> Typecheck<'a> {
metadata: &'a mut FnvMap<Symbol, Metadata>,
) -> Typecheck<'a> {
let symbols = SymbolModule::new(module, symbols);
let kind_cache = KindCache::new();
let subs = Substitution::new(kind_cache.typ(), interner.clone());
let subs = Substitution::new(interner.kind_cache.typ(), interner.clone());
Typecheck {
environment: Environment {
environment,
stack: ScopedMap::new(),
stack_types: ScopedMap::new(),
kind_cache: interner.kind_cache.clone(),
},
symbols: symbols,
named_variables: FnvMap::default(),
errors: Errors::new(),
type_variables: ScopedMap::new(),
kind_cache: kind_cache,
kind_cache: interner.kind_cache.clone(),
implicit_resolver: crate::implicits::ImplicitResolver::new(environment, metadata),
unbound_variables: ScopedMap::new(),
subs,
Expand Down
11 changes: 7 additions & 4 deletions completion/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,10 @@ impl<E: TypeEnv<Type = ArcType>> OnFound for Suggest<E> {
}
self.type_stack.insert(
alias.name.clone(),
alias.unresolved_type().kind().into_owned(),
alias
.unresolved_type()
.kind(&Default::default())
.into_owned(),
);
}
}
Expand Down Expand Up @@ -609,7 +612,7 @@ where
self.found = MatchState::Found(Match::Type(
bind.name.span,
&bind.alias.value.name,
bind.alias.value.kind().into_owned(),
bind.alias.value.kind(&Default::default()).into_owned(),
));
} else {
for param in bind.alias.value.params() {
Expand Down Expand Up @@ -718,7 +721,7 @@ where
self.found = MatchState::Found(Match::Type(
typ.span(),
builtin.symbol(),
typ.kind().into_owned(),
typ.kind(&Default::default()).into_owned(),
));
}

Expand All @@ -730,7 +733,7 @@ where
self.found = MatchState::Found(Match::Type(
typ.span(),
&alias.name,
typ.kind().into_owned(),
typ.kind(&Default::default()).into_owned(),
));
}

Expand Down

0 comments on commit 2911d7e

Please sign in to comment.