Skip to content

Commit

Permalink
perf: Remove Substitution::set_type
Browse files Browse the repository at this point in the history
Replaced by generalize_type in all places
  • Loading branch information
Marwes committed Apr 28, 2018
1 parent d928abc commit 4c751ab
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 97 deletions.
61 changes: 0 additions & 61 deletions check/src/substitution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ use std::fmt;

use union_find::{QuickFindUf, Union, UnionByRank, UnionFind, UnionResult};

use base::fnv::FnvMap;
use base::fixed::{FixedMap, FixedVec};
use base::types;
use base::types::{ArcType, Type, Walker};
use base::symbol::Symbol;

#[derive(Debug, PartialEq)]
pub enum Error<T> {
Expand All @@ -29,8 +27,6 @@ where
}
}

use typecheck::unroll_typ;

pub struct Substitution<T>
where
T: Substitutable,
Expand Down Expand Up @@ -338,63 +334,6 @@ pub fn is_variable_unified(subs: &Substitution<ArcType>, var: &ArcType) -> bool
}
}

impl Substitution<ArcType> {
fn replace_variable_(&self, typ: &Type<Symbol>) -> Option<ArcType> {
match *typ {
Type::Variable(ref id) => self.find_type_for_var(id.id).cloned(),
_ => None,
}
}

pub fn set_type(&self, t: ArcType) -> ArcType {
self.set_type_(&t).unwrap_or(t)
}
fn set_type_(&self, typ: &ArcType) -> Option<ArcType> {
match **typ {
Type::Forall(ref params, ref typ, Some(ref vars)) => {
let subs = self;
let mut named_variables: FnvMap<_, _> = params
.iter()
.zip(vars)
.filter(|&(_, var)| is_variable_unified(subs, var))
.map(|(param, var)| (param.id.clone(), var.clone()))
.collect();
let typ = typ.instantiate_generics(&mut named_variables);
self.set_type_(&typ).map(|typ| {
if params.len() != named_variables.len() {
let mut new_params = Vec::new();
let mut new_vars = Vec::new();
for (param, var) in params.iter().zip(vars) {
if !is_variable_unified(subs, var) {
new_params.push(param.clone());
new_vars.push(var.clone());
}
}
ArcType::from(Type::Forall(new_params, typ, Some(new_vars)))
} else {
typ
}
})
}
Type::Variable(_) => {
let replacement = self.replace_variable_(typ);
let result = {
let mut typ = typ;
if let Some(ref t) = replacement {
typ = t;
}
unroll_typ(typ)
};
result.or(replacement)
}
_ => types::walk_move_type_opt(
typ,
&mut types::ControlVisitation(|typ: &ArcType| self.set_type_(typ)),
),
}
}
}

impl<T: Substitutable + Clone> Substitution<T> {
pub fn make_real(&self, typ: &mut T) {
*typ = self.real(typ).clone();
Expand Down
43 changes: 7 additions & 36 deletions check/src/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,6 @@ impl<'a> Typecheck<'a> {
fn find(&mut self, id: &Symbol) -> TcResult<ArcType> {
match self.environment.find_type(id).map(ArcType::clone) {
Some(typ) => {
let typ = self.subs.set_type(typ);

self.named_variables.clear();
let typ = new_skolem_scope(&self.subs, &typ);
debug!("Find {} : {}", self.symbols.string(id), typ);
Expand Down Expand Up @@ -2234,7 +2232,7 @@ impl<'a> Typecheck<'a> {
span: Span<BytePos>,
level: u32,
expected: &ArcType,
mut actual: ArcType,
actual: ArcType,
) -> ArcType {
debug!("Merge {} : {}", expected, actual);
let expected = self.skolemize(&expected);
Expand All @@ -2247,16 +2245,13 @@ impl<'a> Typecheck<'a> {
&expected,
&actual,
) {
Ok(typ) => self.subs.set_type(typ),
Ok(typ) => typ,
Err(errors) => {
let mut expected = expected.clone();
expected = self.subs.set_type(expected);
actual = self.subs.set_type(actual);
debug!(
"Error '{:?}' between:\n>> {}\n>> {}",
errors, expected, actual
);
let err = TypeError::Unification(expected, actual, apply_subs(&self.subs, errors));
let err = TypeError::Unification(expected, actual, errors.into());
self.errors.push(Spanned {
span: span,
// TODO Help what caused this unification failure
Expand All @@ -2281,23 +2276,20 @@ impl<'a> Typecheck<'a> {
}
}

fn unify(&self, expected: &ArcType, mut actual: ArcType) -> TcResult<ArcType> {
fn unify(&self, expected: &ArcType, actual: ArcType) -> TcResult<ArcType> {
debug!("Unify start {} <=> {}", expected, actual);
let state = unify_type::State::new(&self.environment, &self.subs);
match unify::unify(&self.subs, state, expected, &actual) {
Ok(typ) => Ok(self.subs.set_type(typ)),
Ok(typ) => Ok(typ),
Err(errors) => {
let mut expected = expected.clone();
expected = self.subs.set_type(expected);
actual = self.subs.set_type(actual);
debug!(
"Error '{:?}' between:\n>> {}\n>> {}",
errors, expected, actual
);
Err(TypeError::Unification(
expected,
expected.clone(),
actual,
apply_subs(&self.subs, errors),
errors.into(),
))
}
}
Expand Down Expand Up @@ -2373,27 +2365,6 @@ fn with_pattern_types<F>(
}
}

fn apply_subs(
subs: &Substitution<ArcType>,
errors: Errors<UnifyTypeError<Symbol>>,
) -> Vec<UnifyTypeError<Symbol>> {
use unify::Error::*;
errors
.into_iter()
.map(|error| match error {
TypeMismatch(expected, actual) => {
TypeMismatch(subs.set_type(expected), subs.set_type(actual))
}
Substitution(err) => Substitution(match err {
substitution::Error::Occurs(var, typ) => {
substitution::Error::Occurs(var, subs.set_type(typ))
}
}),
Other(err) => Other(err),
})
.collect()
}

pub fn extract_generics(args: &[ArcType]) -> Vec<Generic<Symbol>> {
args.iter()
.map(|arg| match **arg {
Expand Down

0 comments on commit 4c751ab

Please sign in to comment.