mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
special-case the closure tags
This commit is contained in:
parent
3e640f78bf
commit
cb8e9acb92
4 changed files with 45 additions and 14 deletions
|
@ -739,11 +739,10 @@ pub fn constrain_expr(
|
||||||
region,
|
region,
|
||||||
);
|
);
|
||||||
|
|
||||||
let ext = Type::Variable(*closure_var);
|
let lambda_set = Type::ClosureTag {
|
||||||
let lambda_set = Type::TagUnion(
|
name: *closure_name,
|
||||||
vec![(TagName::Closure(*closure_name), vec![])],
|
ext: *closure_var,
|
||||||
Box::new(ext),
|
};
|
||||||
);
|
|
||||||
|
|
||||||
let function_type = Type::Function(
|
let function_type = Type::Function(
|
||||||
vec![record_type],
|
vec![record_type],
|
||||||
|
@ -1416,7 +1415,7 @@ fn constrain_closure_size(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let tag_name = roc_module::ident::TagName::Closure(name);
|
let tag_name = TagName::Closure(name);
|
||||||
let closure_type = Type::TagUnion(
|
let closure_type = Type::TagUnion(
|
||||||
vec![(tag_name, tag_arguments)],
|
vec![(tag_name, tag_arguments)],
|
||||||
Box::new(Type::Variable(closure_ext_var)),
|
Box::new(Type::Variable(closure_ext_var)),
|
||||||
|
|
|
@ -690,6 +690,19 @@ fn type_to_variable<'a>(
|
||||||
EmptyRec => Variable::EMPTY_RECORD,
|
EmptyRec => Variable::EMPTY_RECORD,
|
||||||
EmptyTagUnion => Variable::EMPTY_TAG_UNION,
|
EmptyTagUnion => Variable::EMPTY_TAG_UNION,
|
||||||
|
|
||||||
|
ClosureTag { name, ext } => {
|
||||||
|
let tag_name = TagName::Closure(*name);
|
||||||
|
let tag_names = SubsSlice::new(subs.tag_names.len() as u32, 1);
|
||||||
|
|
||||||
|
subs.tag_names.push(tag_name);
|
||||||
|
|
||||||
|
let union_tags = UnionTags::from_slices(tag_names, SubsSlice::default());
|
||||||
|
|
||||||
|
let content = Content::Structure(FlatType::TagUnion(union_tags, *ext));
|
||||||
|
|
||||||
|
register(subs, rank, pools, content)
|
||||||
|
}
|
||||||
|
|
||||||
// This case is important for the rank of boolean variables
|
// This case is important for the rank of boolean variables
|
||||||
Function(arguments, closure_type, ret_type) => {
|
Function(arguments, closure_type, ret_type) => {
|
||||||
let new_arguments = VariableSubsSlice::reserve_into_subs(subs, arguments.len());
|
let new_arguments = VariableSubsSlice::reserve_into_subs(subs, arguments.len());
|
||||||
|
|
|
@ -130,6 +130,11 @@ impl SolvedType {
|
||||||
ext: Box::new(solved_ext),
|
ext: Box::new(solved_ext),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ClosureTag { name, ext } => {
|
||||||
|
let solved_ext = Self::from_type(solved_subs, &Type::Variable(*ext));
|
||||||
|
let solved_tags = vec![(TagName::Closure(*name), vec![])];
|
||||||
|
SolvedType::TagUnion(solved_tags, Box::new(solved_ext))
|
||||||
|
}
|
||||||
TagUnion(tags, box_ext) => {
|
TagUnion(tags, box_ext) => {
|
||||||
let solved_ext = Self::from_type(solved_subs, box_ext);
|
let solved_ext = Self::from_type(solved_subs, box_ext);
|
||||||
let mut solved_tags = Vec::with_capacity(tags.len());
|
let mut solved_tags = Vec::with_capacity(tags.len());
|
||||||
|
|
|
@ -169,6 +169,11 @@ 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>),
|
||||||
|
/// A function name that is used in our defunctionalization algorithm
|
||||||
|
ClosureTag {
|
||||||
|
name: Symbol,
|
||||||
|
ext: Variable,
|
||||||
|
},
|
||||||
Alias {
|
Alias {
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
type_arguments: Vec<(Lowercase, Type)>,
|
type_arguments: Vec<(Lowercase, Type)>,
|
||||||
|
@ -378,6 +383,15 @@ impl fmt::Debug for Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Type::ClosureTag { name, ext } => {
|
||||||
|
write!(f, "ClosureTag(")?;
|
||||||
|
|
||||||
|
name.fmt(f)?;
|
||||||
|
write!(f, ", ")?;
|
||||||
|
ext.fmt(f)?;
|
||||||
|
|
||||||
|
write!(f, ")")
|
||||||
|
}
|
||||||
Type::RecursiveTagUnion(rec, tags, ext) => {
|
Type::RecursiveTagUnion(rec, tags, ext) => {
|
||||||
write!(f, "[")?;
|
write!(f, "[")?;
|
||||||
|
|
||||||
|
@ -462,7 +476,7 @@ impl Type {
|
||||||
use Type::*;
|
use Type::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Variable(v) => {
|
ClosureTag { ext: v, .. } | Variable(v) => {
|
||||||
if let Some(replacement) = substitutions.get(v) {
|
if let Some(replacement) = substitutions.get(v) {
|
||||||
*self = replacement.clone();
|
*self = replacement.clone();
|
||||||
}
|
}
|
||||||
|
@ -590,7 +604,7 @@ impl Type {
|
||||||
arg.substitute_alias(rep_symbol, actual);
|
arg.substitute_alias(rep_symbol, actual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EmptyRec | EmptyTagUnion | Erroneous(_) | Variable(_) => {}
|
EmptyRec | EmptyTagUnion | ClosureTag { .. } | Erroneous(_) | Variable(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,7 +641,7 @@ impl Type {
|
||||||
}
|
}
|
||||||
Apply(symbol, _) if *symbol == rep_symbol => true,
|
Apply(symbol, _) if *symbol == rep_symbol => true,
|
||||||
Apply(_, args) => args.iter().any(|arg| arg.contains_symbol(rep_symbol)),
|
Apply(_, args) => args.iter().any(|arg| arg.contains_symbol(rep_symbol)),
|
||||||
EmptyRec | EmptyTagUnion | Erroneous(_) | Variable(_) => false,
|
EmptyRec | EmptyTagUnion | ClosureTag { .. } | Erroneous(_) | Variable(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,7 +649,7 @@ impl Type {
|
||||||
use Type::*;
|
use Type::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Variable(v) => *v == rep_variable,
|
ClosureTag { ext: v, .. } | Variable(v) => *v == rep_variable,
|
||||||
Function(args, closure, ret) => {
|
Function(args, closure, ret) => {
|
||||||
ret.contains_variable(rep_variable)
|
ret.contains_variable(rep_variable)
|
||||||
|| closure.contains_variable(rep_variable)
|
|| closure.contains_variable(rep_variable)
|
||||||
|
@ -819,7 +833,7 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EmptyRec | EmptyTagUnion | Erroneous(_) | Variable(_) => {}
|
EmptyRec | EmptyTagUnion | ClosureTag { .. } | Erroneous(_) | Variable(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -872,7 +886,7 @@ fn symbols_help(tipe: &Type, accum: &mut ImSet<Symbol>) {
|
||||||
accum.insert(*symbol);
|
accum.insert(*symbol);
|
||||||
args.iter().for_each(|arg| symbols_help(arg, accum));
|
args.iter().for_each(|arg| symbols_help(arg, accum));
|
||||||
}
|
}
|
||||||
EmptyRec | EmptyTagUnion | Erroneous(_) | Variable(_) => {}
|
EmptyRec | EmptyTagUnion | ClosureTag { .. } | Erroneous(_) | Variable(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -882,7 +896,7 @@ fn variables_help(tipe: &Type, accum: &mut ImSet<Variable>) {
|
||||||
match tipe {
|
match tipe {
|
||||||
EmptyRec | EmptyTagUnion | Erroneous(_) => (),
|
EmptyRec | EmptyTagUnion | Erroneous(_) => (),
|
||||||
|
|
||||||
Variable(v) => {
|
ClosureTag { ext: v, .. } | Variable(v) => {
|
||||||
accum.insert(*v);
|
accum.insert(*v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,7 +993,7 @@ fn variables_help_detailed(tipe: &Type, accum: &mut VariableDetail) {
|
||||||
match tipe {
|
match tipe {
|
||||||
EmptyRec | EmptyTagUnion | Erroneous(_) => (),
|
EmptyRec | EmptyTagUnion | Erroneous(_) => (),
|
||||||
|
|
||||||
Variable(v) => {
|
ClosureTag { ext: v, .. } | Variable(v) => {
|
||||||
accum.type_variables.insert(*v);
|
accum.type_variables.insert(*v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue