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