Skip to content

Commit

Permalink
perf(check): Only initialize the variable generator when it is necess…
Browse files Browse the repository at this point in the history
…ary (-3%)
  • Loading branch information
Marwes committed Aug 31, 2019
1 parent 0ea13ff commit 793b658
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
12 changes: 7 additions & 5 deletions check/src/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::base::{
symbol::{Symbol, SymbolModule, SymbolRef, Symbols},
types::{
self, Alias, AliasRef, AppVec, ArcType, ArgType, Field, Flags, Generic, PrimitiveEnv, Type,
TypeCache, TypeContext, TypeEnv, TypeExt,
TypeCache, TypeContext, TypeEnv, TypeExt, Walker,
},
};

Expand Down Expand Up @@ -1445,15 +1445,16 @@ impl<'a> Typecheck<'a> {
}

let mut modifier = TypeModifier::Rigid;
types::walk_type(&self.subs.zonk(&original_func_type), &mut |typ: &RcType| {
types::FlagsVisitor(Flags::HAS_VARIABLES, |typ: &RcType| {
if modifier == TypeModifier::Rigid {
if let Type::Variable(var) = &**typ {
if !return_variables.contains(&var.id) {
modifier = TypeModifier::Wobbly;
}
}
}
});
})
.walk(&self.subs.zonk(&original_func_type));

Ok(TailCall::Type(ModType::new(modifier, func_type)))
}
Expand Down Expand Up @@ -2913,7 +2914,7 @@ impl<'a> Typecheck<'a> {
let new_type = f(self, ModType::new(original_type.modifier, skolemized));

let original_type = self.subs.zonk(&original_type);
types::walk_type(&original_type, &mut |typ: &RcType| {
types::FlagsVisitor(Flags::HAS_SKOLEMS, |typ: &RcType| {
if let Type::Skolem(skolem) = &**typ {
if !self.environment.skolem_variables.contains_key(&skolem.name) {
self.error(
Expand All @@ -2925,7 +2926,8 @@ impl<'a> Typecheck<'a> {
);
}
}
});
})
.walk(&original_type);

self.with_forall(&original_type, new_type)
}
Expand Down
17 changes: 14 additions & 3 deletions check/src/typecheck/generalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ pub(crate) struct TypeGeneralizer<'a, 'b: 'a> {
/// We delay updating the substitution until after all recursive bindings have been typechecked
/// to ensure that they get can figure out which variable got generalized for each binding
delayed_generalizations: Vec<(u32, RcType)>,
variable_generator: TypeVariableGenerator,
variable_generator: Option<TypeVariableGenerator>,
top_type: RcType,
pub tc: &'a mut Typecheck<'b>,
span: Span<BytePos>,
}
Expand Down Expand Up @@ -55,7 +56,8 @@ impl<'a, 'b> TypeGeneralizer<'a, 'b> {
level,
unbound_variables: Default::default(),
delayed_generalizations: Vec::new(),
variable_generator: TypeVariableGenerator::new(&tc.subs, typ),
variable_generator: None,
top_type: typ.clone(),
tc,
span,
}
Expand Down Expand Up @@ -152,9 +154,18 @@ impl<'a, 'b> TypeGeneralizer<'a, 'b> {
let Self {
tc,
variable_generator,
top_type,
..
} = self;
let gen = self.unbound_variables.entry(var.id).or_insert_with(|| {
let variable_generator = match variable_generator {
Some(v) => v,
None => {
*variable_generator =
Some(TypeVariableGenerator::new(&tc.subs, top_type));
variable_generator.as_mut().unwrap()
}
};
// Create a prefix if none exists
let id = variable_generator.next_variable(tc);

Expand Down Expand Up @@ -249,7 +260,7 @@ impl TypeVariableGenerator {
gather_foralls(&mut map, subs, typ);
TypeVariableGenerator {
map,
name: "".to_string(),
name: String::new(),
i: 0,
}
}
Expand Down

0 comments on commit 793b658

Please sign in to comment.