mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 07:49:17 +03:00
store lambda set in alias types
This commit is contained in:
parent
dad5d5de85
commit
4cefbec5c7
@ -234,7 +234,12 @@ fn can_annotation_help(
|
||||
// instantiate variables
|
||||
actual.substitute(&substitutions);
|
||||
|
||||
Type::Alias(symbol, vars, Box::new(actual))
|
||||
Type::Alias {
|
||||
symbol,
|
||||
type_arguments: vars,
|
||||
lambda_set_variables: alias.lambda_set_variables.clone(),
|
||||
actual: Box::new(actual),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let mut args = Vec::new();
|
||||
@ -378,7 +383,12 @@ fn can_annotation_help(
|
||||
actual_var,
|
||||
}
|
||||
} else {
|
||||
Type::Alias(symbol, vars, Box::new(alias.typ.clone()))
|
||||
Type::Alias {
|
||||
symbol,
|
||||
type_arguments: vars,
|
||||
lambda_set_variables: alias.lambda_set_variables.clone(),
|
||||
actual: Box::new(alias.typ.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -76,7 +76,7 @@ fn subtract(declared: &Declared, detail: &VariableDetail, accum: &mut VariableDe
|
||||
}
|
||||
|
||||
if !declared.flex_vars.contains(&var.into_inner()) {
|
||||
accum.lambda_set_variables.insert(*var);
|
||||
accum.lambda_set_variables.push(*var);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1634,7 +1634,7 @@ fn make_tag_union_recursive<'a>(
|
||||
typ.substitute_alias(symbol, &Type::Variable(rec_var));
|
||||
}
|
||||
Type::RecursiveTagUnion(_, _, _) => {}
|
||||
Type::Alias(_, _, actual) => make_tag_union_recursive(
|
||||
Type::Alias { actual, .. } => make_tag_union_recursive(
|
||||
env,
|
||||
symbol,
|
||||
region,
|
||||
|
@ -47,7 +47,7 @@ impl Scope {
|
||||
let alias = Alias {
|
||||
region,
|
||||
typ,
|
||||
lambda_set_variables: MutSet::default(),
|
||||
lambda_set_variables: Vec::new(),
|
||||
recursion_variables: MutSet::default(),
|
||||
type_variables: variables,
|
||||
};
|
||||
|
@ -2,7 +2,7 @@ use roc_can::constraint::Constraint::{self, *};
|
||||
use roc_can::constraint::LetConstraint;
|
||||
use roc_can::expected::Expected::{self, *};
|
||||
use roc_collections::all::SendMap;
|
||||
use roc_module::ident::TagName;
|
||||
use roc_module::ident::{Lowercase, TagName};
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_region::all::Region;
|
||||
use roc_types::subs::Variable;
|
||||
@ -89,9 +89,23 @@ pub fn str_type() -> Type {
|
||||
builtin_type(Symbol::STR_STR, Vec::new())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn builtin_alias(
|
||||
symbol: Symbol,
|
||||
type_arguments: Vec<(Lowercase, Type)>,
|
||||
actual: Box<Type>,
|
||||
) -> Type {
|
||||
Type::Alias {
|
||||
symbol,
|
||||
type_arguments,
|
||||
actual,
|
||||
lambda_set_variables: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn num_float(range: Type) -> Type {
|
||||
Type::Alias(
|
||||
builtin_alias(
|
||||
Symbol::NUM_FLOAT,
|
||||
vec![("range".into(), range.clone())],
|
||||
Box::new(num_num(num_floatingpoint(range))),
|
||||
@ -108,7 +122,7 @@ pub fn num_floatingpoint(range: Type) -> Type {
|
||||
Box::new(Type::EmptyTagUnion),
|
||||
);
|
||||
|
||||
Type::Alias(
|
||||
builtin_alias(
|
||||
Symbol::NUM_FLOATINGPOINT,
|
||||
vec![("range".into(), range)],
|
||||
Box::new(alias_content),
|
||||
@ -122,12 +136,12 @@ pub fn num_binary64() -> Type {
|
||||
Box::new(Type::EmptyTagUnion),
|
||||
);
|
||||
|
||||
Type::Alias(Symbol::NUM_BINARY64, vec![], Box::new(alias_content))
|
||||
builtin_alias(Symbol::NUM_BINARY64, vec![], Box::new(alias_content))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn num_int(range: Type) -> Type {
|
||||
Type::Alias(
|
||||
builtin_alias(
|
||||
Symbol::NUM_INT,
|
||||
vec![("range".into(), range.clone())],
|
||||
Box::new(num_num(num_integer(range))),
|
||||
@ -141,7 +155,7 @@ pub fn num_signed64() -> Type {
|
||||
Box::new(Type::EmptyTagUnion),
|
||||
);
|
||||
|
||||
Type::Alias(Symbol::NUM_SIGNED64, vec![], Box::new(alias_content))
|
||||
builtin_alias(Symbol::NUM_SIGNED64, vec![], Box::new(alias_content))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@ -154,7 +168,7 @@ pub fn num_integer(range: Type) -> Type {
|
||||
Box::new(Type::EmptyTagUnion),
|
||||
);
|
||||
|
||||
Type::Alias(
|
||||
builtin_alias(
|
||||
Symbol::NUM_INTEGER,
|
||||
vec![("range".into(), range)],
|
||||
Box::new(alias_content),
|
||||
@ -168,7 +182,7 @@ pub fn num_num(typ: Type) -> Type {
|
||||
Box::new(Type::EmptyTagUnion),
|
||||
);
|
||||
|
||||
Type::Alias(
|
||||
builtin_alias(
|
||||
Symbol::NUM_NUM,
|
||||
vec![("range".into(), typ)],
|
||||
Box::new(alias_content),
|
||||
|
@ -1,3 +1,4 @@
|
||||
use roc_can::annotation::IntroducedVariables;
|
||||
use roc_can::def::{Declaration, Def};
|
||||
use roc_can::env::Env;
|
||||
use roc_can::expr::{Expr, Recursive};
|
||||
@ -160,25 +161,22 @@ fn build_effect_always(
|
||||
(function_var, closure)
|
||||
};
|
||||
|
||||
use roc_can::annotation::IntroducedVariables;
|
||||
|
||||
let mut introduced_variables = IntroducedVariables::default();
|
||||
|
||||
let signature = {
|
||||
// Effect.always : a -> Effect a
|
||||
let var_a = var_store.fresh();
|
||||
|
||||
introduced_variables.insert_named("a".into(), var_a);
|
||||
|
||||
let effect_a = {
|
||||
let actual = build_effect_actual(effect_tag_name, Type::Variable(var_a), var_store);
|
||||
|
||||
Type::Alias(
|
||||
effect_symbol,
|
||||
vec![("a".into(), Type::Variable(var_a))],
|
||||
Box::new(actual),
|
||||
)
|
||||
};
|
||||
let effect_a = build_effect_alias(
|
||||
effect_symbol,
|
||||
effect_tag_name,
|
||||
"a",
|
||||
var_a,
|
||||
Type::Variable(var_a),
|
||||
var_store,
|
||||
&mut introduced_variables,
|
||||
);
|
||||
|
||||
let closure_var = var_store.fresh();
|
||||
introduced_variables.insert_wildcard(closure_var);
|
||||
@ -353,8 +351,6 @@ fn build_effect_map(
|
||||
loc_body: Box::new(Located::at_zero(body)),
|
||||
};
|
||||
|
||||
use roc_can::annotation::IntroducedVariables;
|
||||
|
||||
let mut introduced_variables = IntroducedVariables::default();
|
||||
|
||||
let signature = {
|
||||
@ -365,26 +361,25 @@ fn build_effect_map(
|
||||
introduced_variables.insert_named("a".into(), var_a);
|
||||
introduced_variables.insert_named("b".into(), var_b);
|
||||
|
||||
let effect_a = {
|
||||
let actual =
|
||||
build_effect_actual(effect_tag_name.clone(), Type::Variable(var_a), var_store);
|
||||
let effect_a = build_effect_alias(
|
||||
effect_symbol,
|
||||
effect_tag_name.clone(),
|
||||
"a",
|
||||
var_a,
|
||||
Type::Variable(var_a),
|
||||
var_store,
|
||||
&mut introduced_variables,
|
||||
);
|
||||
|
||||
Type::Alias(
|
||||
effect_symbol,
|
||||
vec![("a".into(), Type::Variable(var_a))],
|
||||
Box::new(actual),
|
||||
)
|
||||
};
|
||||
|
||||
let effect_b = {
|
||||
let actual = build_effect_actual(effect_tag_name, Type::Variable(var_b), var_store);
|
||||
|
||||
Type::Alias(
|
||||
effect_symbol,
|
||||
vec![("b".into(), Type::Variable(var_b))],
|
||||
Box::new(actual),
|
||||
)
|
||||
};
|
||||
let effect_b = build_effect_alias(
|
||||
effect_symbol,
|
||||
effect_tag_name,
|
||||
"b",
|
||||
var_b,
|
||||
Type::Variable(var_b),
|
||||
var_store,
|
||||
&mut introduced_variables,
|
||||
);
|
||||
|
||||
let closure_var = var_store.fresh();
|
||||
introduced_variables.insert_wildcard(closure_var);
|
||||
@ -526,8 +521,6 @@ fn build_effect_after(
|
||||
loc_body: Box::new(Located::at_zero(to_effect_call)),
|
||||
};
|
||||
|
||||
use roc_can::annotation::IntroducedVariables;
|
||||
|
||||
let mut introduced_variables = IntroducedVariables::default();
|
||||
|
||||
let signature = {
|
||||
@ -537,26 +530,25 @@ fn build_effect_after(
|
||||
introduced_variables.insert_named("a".into(), var_a);
|
||||
introduced_variables.insert_named("b".into(), var_b);
|
||||
|
||||
let effect_a = {
|
||||
let actual =
|
||||
build_effect_actual(effect_tag_name.clone(), Type::Variable(var_a), var_store);
|
||||
let effect_a = build_effect_alias(
|
||||
effect_symbol,
|
||||
effect_tag_name.clone(),
|
||||
"a",
|
||||
var_a,
|
||||
Type::Variable(var_a),
|
||||
var_store,
|
||||
&mut introduced_variables,
|
||||
);
|
||||
|
||||
Type::Alias(
|
||||
effect_symbol,
|
||||
vec![("a".into(), Type::Variable(var_a))],
|
||||
Box::new(actual),
|
||||
)
|
||||
};
|
||||
|
||||
let effect_b = {
|
||||
let actual = build_effect_actual(effect_tag_name, Type::Variable(var_b), var_store);
|
||||
|
||||
Type::Alias(
|
||||
effect_symbol,
|
||||
vec![("b".into(), Type::Variable(var_b))],
|
||||
Box::new(actual),
|
||||
)
|
||||
};
|
||||
let effect_b = build_effect_alias(
|
||||
effect_symbol,
|
||||
effect_tag_name,
|
||||
"b",
|
||||
var_b,
|
||||
Type::Variable(var_b),
|
||||
var_store,
|
||||
&mut introduced_variables,
|
||||
);
|
||||
|
||||
let closure_var = var_store.fresh();
|
||||
introduced_variables.insert_wildcard(closure_var);
|
||||
@ -763,6 +755,40 @@ pub fn build_host_exposed_def(
|
||||
}
|
||||
}
|
||||
|
||||
fn build_effect_alias(
|
||||
effect_symbol: Symbol,
|
||||
effect_tag_name: TagName,
|
||||
a_name: &str,
|
||||
a_var: Variable,
|
||||
a_type: Type,
|
||||
var_store: &mut VarStore,
|
||||
introduced_variables: &mut IntroducedVariables,
|
||||
) -> Type {
|
||||
let closure_var = var_store.fresh();
|
||||
introduced_variables.insert_wildcard(closure_var);
|
||||
|
||||
let actual = {
|
||||
Type::TagUnion(
|
||||
vec![(
|
||||
effect_tag_name,
|
||||
vec![Type::Function(
|
||||
vec![Type::EmptyRec],
|
||||
Box::new(Type::Variable(closure_var)),
|
||||
Box::new(a_type),
|
||||
)],
|
||||
)],
|
||||
Box::new(Type::EmptyTagUnion),
|
||||
)
|
||||
};
|
||||
|
||||
Type::Alias {
|
||||
symbol: effect_symbol,
|
||||
type_arguments: vec![(a_name.into(), Type::Variable(a_var))],
|
||||
lambda_set_variables: vec![roc_types::subs::LambdaSet(closure_var)],
|
||||
actual: Box::new(actual),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_effect_actual(
|
||||
effect_tag_name: TagName,
|
||||
a_type: Type,
|
||||
|
@ -790,8 +790,14 @@ fn type_to_variable(
|
||||
|
||||
tag_union_var
|
||||
}
|
||||
Alias(Symbol::BOOL_BOOL, _, _) => Variable::BOOL,
|
||||
Alias(symbol, args, alias_type) => {
|
||||
|
||||
Type::Alias {
|
||||
symbol,
|
||||
type_arguments: args,
|
||||
actual: alias_type,
|
||||
lambda_set_variables,
|
||||
} => {
|
||||
dbg!(lambda_set_variables);
|
||||
let mut arg_vars = Vec::with_capacity(args.len());
|
||||
|
||||
for (arg, arg_type) in args {
|
||||
|
@ -183,6 +183,7 @@ pub enum SolvedType {
|
||||
Erroneous(Problem),
|
||||
|
||||
/// A type alias
|
||||
/// TODO transmit lambda sets!
|
||||
Alias(Symbol, Vec<(Lowercase, SolvedType)>, Box<SolvedType>),
|
||||
|
||||
HostExposedAlias {
|
||||
@ -293,11 +294,16 @@ impl SolvedType {
|
||||
)
|
||||
}
|
||||
Erroneous(problem) => SolvedType::Erroneous(problem.clone()),
|
||||
Alias(symbol, args, box_type) => {
|
||||
Alias {
|
||||
symbol,
|
||||
type_arguments,
|
||||
actual: box_type,
|
||||
..
|
||||
} => {
|
||||
let solved_type = Self::from_type(solved_subs, box_type);
|
||||
let mut solved_args = Vec::with_capacity(args.len());
|
||||
let mut solved_args = Vec::with_capacity(type_arguments.len());
|
||||
|
||||
for (name, var) in args {
|
||||
for (name, var) in type_arguments {
|
||||
solved_args.push((name.clone(), Self::from_type(solved_subs, var)));
|
||||
}
|
||||
|
||||
@ -617,7 +623,12 @@ pub fn to_type(
|
||||
|
||||
let actual = to_type(solved_actual, free_vars, var_store);
|
||||
|
||||
Type::Alias(*symbol, type_variables, Box::new(actual))
|
||||
Type::Alias {
|
||||
symbol: *symbol,
|
||||
type_arguments: type_variables,
|
||||
lambda_set_variables: vec![], // TODO transfer lambda sets
|
||||
actual: Box::new(actual),
|
||||
}
|
||||
}
|
||||
HostExposedAlias {
|
||||
name,
|
||||
|
@ -206,7 +206,7 @@ impl UnifyKey for Variable {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct LambdaSet(Variable);
|
||||
pub struct LambdaSet(pub Variable);
|
||||
|
||||
impl fmt::Debug for LambdaSet {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
@ -12,6 +12,11 @@ pub const TYPE_NUM: &str = "Num";
|
||||
pub const TYPE_INTEGER: &str = "Integer";
|
||||
pub const TYPE_FLOATINGPOINT: &str = "FloatingPoint";
|
||||
|
||||
const GREEK_LETTERS: &[char] = &[
|
||||
'α', 'ν', 'β', 'ξ', 'γ', 'ο', 'δ', 'π', 'ε', 'ρ', 'ζ', 'σ', 'η', 'τ', 'θ', 'υ', 'ι', 'φ', 'κ',
|
||||
'χ', 'λ', 'ψ', 'μ', 'ω', 'ς',
|
||||
];
|
||||
|
||||
///
|
||||
/// Intuitively
|
||||
///
|
||||
@ -142,7 +147,12 @@ pub enum Type {
|
||||
Record(SendMap<Lowercase, RecordField<Type>>, Box<Type>),
|
||||
TagUnion(Vec<(TagName, Vec<Type>)>, Box<Type>),
|
||||
FunctionOrTagUnion(TagName, Symbol, Box<Type>),
|
||||
Alias(Symbol, Vec<(Lowercase, Type)>, Box<Type>),
|
||||
Alias {
|
||||
symbol: Symbol,
|
||||
type_arguments: Vec<(Lowercase, Type)>,
|
||||
lambda_set_variables: Vec<LambdaSet>,
|
||||
actual: Box<Type>,
|
||||
},
|
||||
HostExposedAlias {
|
||||
name: Symbol,
|
||||
arguments: Vec<(Lowercase, Type)>,
|
||||
@ -198,13 +208,22 @@ impl fmt::Debug for Type {
|
||||
|
||||
write!(f, ")")
|
||||
}
|
||||
Type::Alias(symbol, args, _actual) => {
|
||||
Type::Alias {
|
||||
symbol,
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
..
|
||||
} => {
|
||||
write!(f, "Alias {:?}", symbol)?;
|
||||
|
||||
for (_, arg) in args {
|
||||
for (_, arg) in type_arguments {
|
||||
write!(f, " {:?}", arg)?;
|
||||
}
|
||||
|
||||
for (_, greek_letter) in lambda_set_variables.iter().zip(GREEK_LETTERS.iter()) {
|
||||
write!(f, " {:?}", greek_letter)?;
|
||||
}
|
||||
|
||||
// Sometimes it's useful to see the expansion of the alias
|
||||
// write!(f, "[ but actually {:?} ]", _actual)?;
|
||||
|
||||
@ -442,11 +461,16 @@ impl Type {
|
||||
}
|
||||
ext.substitute(substitutions);
|
||||
}
|
||||
Alias(_, zipped, actual_type) => {
|
||||
for (_, value) in zipped.iter_mut() {
|
||||
Alias {
|
||||
type_arguments,
|
||||
actual,
|
||||
..
|
||||
} => {
|
||||
for (_, value) in type_arguments.iter_mut() {
|
||||
value.substitute(substitutions);
|
||||
}
|
||||
actual_type.substitute(substitutions);
|
||||
|
||||
actual.substitute(substitutions);
|
||||
}
|
||||
HostExposedAlias {
|
||||
arguments,
|
||||
@ -497,8 +521,11 @@ impl Type {
|
||||
}
|
||||
ext.substitute_alias(rep_symbol, actual);
|
||||
}
|
||||
Alias(_, _, actual_type) => {
|
||||
actual_type.substitute_alias(rep_symbol, actual);
|
||||
Alias {
|
||||
actual: alias_actual,
|
||||
..
|
||||
} => {
|
||||
alias_actual.substitute_alias(rep_symbol, actual);
|
||||
}
|
||||
HostExposedAlias {
|
||||
actual: actual_type,
|
||||
@ -547,9 +574,11 @@ impl Type {
|
||||
ext.contains_symbol(rep_symbol)
|
||||
|| fields.values().any(|arg| arg.contains_symbol(rep_symbol))
|
||||
}
|
||||
Alias(alias_symbol, _, actual_type) => {
|
||||
alias_symbol == &rep_symbol || actual_type.contains_symbol(rep_symbol)
|
||||
}
|
||||
Alias {
|
||||
symbol: alias_symbol,
|
||||
actual: actual_type,
|
||||
..
|
||||
} => alias_symbol == &rep_symbol || actual_type.contains_symbol(rep_symbol),
|
||||
HostExposedAlias { name, actual, .. } => {
|
||||
name == &rep_symbol || actual.contains_symbol(rep_symbol)
|
||||
}
|
||||
@ -585,7 +614,10 @@ impl Type {
|
||||
.values()
|
||||
.any(|arg| arg.contains_variable(rep_variable))
|
||||
}
|
||||
Alias(_, _, actual_type) => actual_type.contains_variable(rep_variable),
|
||||
Alias {
|
||||
actual: actual_type,
|
||||
..
|
||||
} => actual_type.contains_variable(rep_variable),
|
||||
HostExposedAlias { actual, .. } => actual.contains_variable(rep_variable),
|
||||
Apply(_, args) => args.iter().any(|arg| arg.contains_variable(rep_variable)),
|
||||
EmptyRec | EmptyTagUnion | Erroneous(_) => false,
|
||||
@ -602,7 +634,7 @@ impl Type {
|
||||
/// a shallow dealias, continue until the first constructor is not an alias.
|
||||
pub fn shallow_dealias(&self) -> &Self {
|
||||
match self {
|
||||
Type::Alias(_, _, actual) => actual.shallow_dealias(),
|
||||
Type::Alias { actual, .. } => actual.shallow_dealias(),
|
||||
_ => self,
|
||||
}
|
||||
}
|
||||
@ -646,7 +678,11 @@ impl Type {
|
||||
actual: actual_type,
|
||||
..
|
||||
}
|
||||
| Alias(_, type_args, actual_type) => {
|
||||
| Alias {
|
||||
type_arguments: type_args,
|
||||
actual: actual_type,
|
||||
..
|
||||
} => {
|
||||
for arg in type_args {
|
||||
arg.1
|
||||
.instantiate_aliases(region, aliases, var_store, introduced);
|
||||
@ -737,13 +773,19 @@ impl Type {
|
||||
}
|
||||
ext.substitute(&substitution);
|
||||
|
||||
*self = Type::Alias(
|
||||
*symbol,
|
||||
named_args,
|
||||
Box::new(Type::RecursiveTagUnion(new_rec_var, tags, ext)),
|
||||
);
|
||||
*self = Type::Alias {
|
||||
symbol: *symbol,
|
||||
type_arguments: named_args,
|
||||
lambda_set_variables: alias.lambda_set_variables.clone(),
|
||||
actual: Box::new(Type::RecursiveTagUnion(new_rec_var, tags, ext)),
|
||||
};
|
||||
} else {
|
||||
*self = Type::Alias(*symbol, named_args, Box::new(actual));
|
||||
*self = Type::Alias {
|
||||
symbol: *symbol,
|
||||
type_arguments: named_args,
|
||||
lambda_set_variables: alias.lambda_set_variables.clone(),
|
||||
actual: Box::new(actual),
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// one of the special-cased Apply types.
|
||||
@ -789,7 +831,11 @@ fn symbols_help(tipe: &Type, accum: &mut ImSet<Symbol>) {
|
||||
}
|
||||
});
|
||||
}
|
||||
Alias(alias_symbol, _, actual_type) => {
|
||||
Alias {
|
||||
symbol: alias_symbol,
|
||||
actual: actual_type,
|
||||
..
|
||||
} => {
|
||||
accum.insert(*alias_symbol);
|
||||
symbols_help(&actual_type, accum);
|
||||
}
|
||||
@ -859,8 +905,12 @@ fn variables_help(tipe: &Type, accum: &mut ImSet<Variable>) {
|
||||
// this rec var doesn't need to be in flex_vars or rigid_vars
|
||||
accum.remove(rec);
|
||||
}
|
||||
Alias(_, args, actual) => {
|
||||
for (_, arg) in args {
|
||||
Alias {
|
||||
type_arguments,
|
||||
actual,
|
||||
..
|
||||
} => {
|
||||
for (_, arg) in type_arguments {
|
||||
variables_help(arg, accum);
|
||||
}
|
||||
variables_help(actual, accum);
|
||||
@ -884,7 +934,7 @@ fn variables_help(tipe: &Type, accum: &mut ImSet<Variable>) {
|
||||
#[derive(Default)]
|
||||
pub struct VariableDetail {
|
||||
pub type_variables: MutSet<Variable>,
|
||||
pub lambda_set_variables: MutSet<LambdaSet>,
|
||||
pub lambda_set_variables: Vec<LambdaSet>,
|
||||
pub recursion_variables: MutSet<Variable>,
|
||||
}
|
||||
|
||||
@ -911,7 +961,7 @@ fn variables_help_detailed(tipe: &Type, accum: &mut VariableDetail) {
|
||||
variables_help_detailed(arg, accum);
|
||||
}
|
||||
if let Type::Variable(v) = **closure {
|
||||
accum.lambda_set_variables.insert(LambdaSet::from(v));
|
||||
accum.lambda_set_variables.push(LambdaSet::from(v));
|
||||
} else {
|
||||
variables_help_detailed(closure, accum);
|
||||
}
|
||||
@ -957,8 +1007,12 @@ fn variables_help_detailed(tipe: &Type, accum: &mut VariableDetail) {
|
||||
|
||||
accum.recursion_variables.insert(*rec);
|
||||
}
|
||||
Alias(_, args, actual) => {
|
||||
for (_, arg) in args {
|
||||
Alias {
|
||||
type_arguments,
|
||||
actual,
|
||||
..
|
||||
} => {
|
||||
for (_, arg) in type_arguments {
|
||||
variables_help_detailed(arg, accum);
|
||||
}
|
||||
variables_help_detailed(actual, accum);
|
||||
@ -1106,7 +1160,7 @@ pub struct Alias {
|
||||
|
||||
/// lambda set variables, e.g. the one annotating the arrow in
|
||||
/// a |c|-> b
|
||||
pub lambda_set_variables: MutSet<LambdaSet>,
|
||||
pub lambda_set_variables: Vec<LambdaSet>,
|
||||
|
||||
pub recursion_variables: MutSet<Variable>,
|
||||
|
||||
|
@ -767,7 +767,6 @@ fn type_to_variable<'a>(
|
||||
register(subs, rank, pools, content)
|
||||
}
|
||||
|
||||
Alias(Symbol::BOOL_BOOL, _, _) => roc_types::subs::Variable::BOOL,
|
||||
Alias(symbol, args, alias_type_id) => {
|
||||
// TODO cache in uniqueness inference gives problems! all Int's get the same uniqueness var!
|
||||
// Cache aliases without type arguments. Commonly used aliases like `Int` would otherwise get O(n)
|
||||
|
Loading…
Reference in New Issue
Block a user