collect and instantiate hidden variables

This commit is contained in:
Folkert 2020-10-25 19:11:03 +01:00
parent 2c55fa5ec5
commit f13c28fe7f
5 changed files with 59 additions and 19 deletions

View file

@ -195,6 +195,18 @@ fn can_annotation_help(
vars.push((name.clone(), arg_ann)); vars.push((name.clone(), arg_ann));
} }
// make sure the recursion variable is freshly instantiated
if let Type::RecursiveTagUnion(rvar, _, _) = &mut actual {
let new = var_store.fresh();
substitutions.insert(*rvar, Type::Variable(new));
*rvar = new;
}
// make sure hidden variables are freshly instantiated
for var in alias.hidden_variables.iter() {
substitutions.insert(*var, Type::Variable(var_store.fresh()));
}
// instantiate variables // instantiate variables
actual.substitute(&substitutions); actual.substitute(&substitutions);
@ -320,9 +332,17 @@ fn can_annotation_help(
inner_type inner_type
}; };
let mut hidden_variables = MutSet::default();
hidden_variables.extend(alias_actual.variables());
for loc_var in lowercase_vars.iter() {
hidden_variables.remove(&loc_var.value.1);
}
let alias = Alias { let alias = Alias {
region, region,
vars: lowercase_vars, vars: lowercase_vars,
hidden_variables,
uniqueness: None, uniqueness: None,
typ: alias_actual, typ: alias_actual,
}; };

View file

@ -281,15 +281,8 @@ pub fn canonicalize_defs<'a>(
} }
scope.add_alias(symbol, ann.region, can_vars.clone(), can_ann.typ.clone()); scope.add_alias(symbol, ann.region, can_vars.clone(), can_ann.typ.clone());
let alias = scope.lookup_alias(symbol).expect("alias is added to scope");
let alias = roc_types::types::Alias { aliases.insert(symbol, alias.clone());
region: ann.region,
vars: can_vars,
uniqueness: None,
typ: can_ann.typ,
};
aliases.insert(symbol, alias);
} }
other => value_defs.push(other), other => value_defs.push(other),
} }

View file

@ -1,4 +1,4 @@
use roc_collections::all::ImMap; use roc_collections::all::{ImMap, MutSet};
use roc_module::ident::{Ident, Lowercase}; use roc_module::ident::{Ident, Lowercase};
use roc_module::symbol::{IdentIds, ModuleId, Symbol}; use roc_module::symbol::{IdentIds, ModuleId, Symbol};
use roc_problem::can::RuntimeError; use roc_problem::can::RuntimeError;
@ -146,14 +146,21 @@ impl Scope {
vars: Vec<Located<(Lowercase, Variable)>>, vars: Vec<Located<(Lowercase, Variable)>>,
typ: Type, typ: Type,
) { ) {
self.aliases.insert( let mut hidden_variables = MutSet::default();
name, hidden_variables.extend(typ.variables());
Alias {
region, for loc_var in vars.iter() {
vars, hidden_variables.remove(&loc_var.value.1);
uniqueness: None, }
typ,
}, let alias = Alias {
); region,
vars,
hidden_variables,
uniqueness: None,
typ,
};
self.aliases.insert(name, alias);
} }
} }

View file

@ -150,8 +150,16 @@ where
)); ));
} }
let mut hidden_variables = MutSet::default();
hidden_variables.extend(actual.variables());
for loc_var in vars.iter() {
hidden_variables.remove(&loc_var.value.1);
}
let alias = Alias { let alias = Alias {
vars, vars,
hidden_variables,
region: builtin_alias.region, region: builtin_alias.region,
uniqueness: None, uniqueness: None,
typ: actual, typ: actual,
@ -196,8 +204,16 @@ pub fn constrain_imported_aliases(
actual.substitute(&substitution); actual.substitute(&substitution);
let mut hidden_variables = MutSet::default();
hidden_variables.extend(actual.variables());
for loc_var in vars.iter() {
hidden_variables.remove(&loc_var.value.1);
}
let alias = Alias { let alias = Alias {
vars, vars,
hidden_variables,
region: imported_alias.region, region: imported_alias.region,
uniqueness: imported_alias.uniqueness, uniqueness: imported_alias.uniqueness,
typ: actual, typ: actual,

View file

@ -984,6 +984,10 @@ pub enum PatternCategory {
pub struct Alias { pub struct Alias {
pub region: Region, pub region: Region,
pub vars: Vec<Located<(Lowercase, Variable)>>, pub vars: Vec<Located<(Lowercase, Variable)>>,
/// hidden type variables, like the closure variable in `a -> b`
pub hidden_variables: MutSet<Variable>,
pub uniqueness: Option<boolean_algebra::Bool>, pub uniqueness: Option<boolean_algebra::Bool>,
pub typ: Type, pub typ: Type,
} }