use a SubsIndex instead of Box

This commit is contained in:
Folkert 2021-08-07 13:50:53 +02:00
parent dd73428dc1
commit ad3d006a11
7 changed files with 65 additions and 30 deletions

View file

@ -168,13 +168,21 @@ fn jit_to_ast_help<'a>(
env, env,
ptr, ptr,
field_layouts, field_layouts,
tag_name.clone(), tag_name,
payload_vars, payload_vars,
)) ))
} }
Content::Structure(FlatType::FunctionOrTagUnion(tag_name, _, _)) => Ok( Content::Structure(FlatType::FunctionOrTagUnion(tag_name, _, _)) => {
single_tag_union_to_ast(env, ptr, field_layouts, *tag_name.clone(), &[]), let tag_name = &env.subs[*tag_name];
),
Ok(single_tag_union_to_ast(
env,
ptr,
field_layouts,
tag_name,
&[],
))
}
Content::Structure(FlatType::Func(_, _, _)) => { Content::Structure(FlatType::Func(_, _, _)) => {
// a function with a struct as the closure environment // a function with a struct as the closure environment
Err(ToAstProblem::FunctionLayout) Err(ToAstProblem::FunctionLayout)
@ -432,10 +440,11 @@ fn ptr_to_ast<'a>(
debug_assert_eq!(tags.len(), 1); debug_assert_eq!(tags.len(), 1);
let (tag_name, payload_vars) = tags.iter().next().unwrap(); let (tag_name, payload_vars) = tags.iter().next().unwrap();
single_tag_union_to_ast(env, ptr, field_layouts, tag_name.clone(), payload_vars) single_tag_union_to_ast(env, ptr, field_layouts, tag_name, payload_vars)
} }
Content::Structure(FlatType::FunctionOrTagUnion(tag_name, _, _)) => { Content::Structure(FlatType::FunctionOrTagUnion(tag_name, _, _)) => {
single_tag_union_to_ast(env, ptr, field_layouts, *tag_name.clone(), &[]) let tag_name = &env.subs[*tag_name];
single_tag_union_to_ast(env, ptr, field_layouts, tag_name, &[])
} }
Content::Structure(FlatType::EmptyRecord) => { Content::Structure(FlatType::EmptyRecord) => {
struct_to_ast(env, ptr, &[], RecordFields::empty()) struct_to_ast(env, ptr, &[], RecordFields::empty())
@ -506,14 +515,14 @@ fn single_tag_union_to_ast<'a>(
env: &Env<'a, '_>, env: &Env<'a, '_>,
ptr: *const u8, ptr: *const u8,
field_layouts: &'a [Layout<'a>], field_layouts: &'a [Layout<'a>],
tag_name: TagName, tag_name: &TagName,
payload_vars: &[Variable], payload_vars: &[Variable],
) -> Expr<'a> { ) -> Expr<'a> {
debug_assert_eq!(field_layouts.len(), payload_vars.len()); debug_assert_eq!(field_layouts.len(), payload_vars.len());
let arena = env.arena; let arena = env.arena;
let tag_expr = tag_name_to_expr(env, &tag_name); let tag_expr = tag_name_to_expr(env, tag_name);
let loc_tag_expr = &*arena.alloc(Located::at_zero(tag_expr)); let loc_tag_expr = &*arena.alloc(Located::at_zero(tag_expr));

View file

@ -1256,7 +1256,7 @@ fn layout_from_flat_type<'a>(
debug_assert!(ext_var_is_empty_tag_union(subs, ext_var)); debug_assert!(ext_var_is_empty_tag_union(subs, ext_var));
let mut tags = MutMap::default(); let mut tags = MutMap::default();
tags.insert(*tag_name, vec![]); tags.insert(subs[tag_name].clone(), vec![]);
Ok(layout_from_tag_union(arena, tags, subs)) Ok(layout_from_tag_union(arena, tags, subs))
} }

View file

@ -5,8 +5,8 @@ use roc_module::symbol::Symbol;
use roc_region::all::{Located, Region}; use roc_region::all::{Located, Region};
use roc_types::solved_types::Solved; use roc_types::solved_types::Solved;
use roc_types::subs::{ use roc_types::subs::{
Content, Descriptor, FlatType, Mark, OptVariable, Rank, RecordFields, Subs, Variable, Content, Descriptor, FlatType, Mark, OptVariable, Rank, RecordFields, Subs, SubsIndex,
VariableSubsSlice, Variable, VariableSubsSlice,
}; };
use roc_types::types::Type::{self, *}; use roc_types::types::Type::{self, *};
use roc_types::types::{Alias, Category, ErrorType, PatternCategory}; use roc_types::types::{Alias, Category, ErrorType, PatternCategory};
@ -746,11 +746,12 @@ fn type_to_variable(
}; };
debug_assert!(ext_tag_vec.is_empty()); debug_assert!(ext_tag_vec.is_empty());
let content = Content::Structure(FlatType::FunctionOrTagUnion( let start = subs.tag_names.len() as u32;
Box::new(tag_name.clone()), subs.tag_names.push(tag_name.clone());
*symbol, let slice = SubsIndex::new(start);
new_ext_var,
)); let content =
Content::Structure(FlatType::FunctionOrTagUnion(slice, *symbol, new_ext_var));
register(subs, rank, pools, content) register(subs, rank, pools, content)
} }

View file

@ -499,7 +499,7 @@ fn write_flat_type(env: &Env, flat_type: &FlatType, subs: &Subs, buf: &mut Strin
buf.push_str("[ "); buf.push_str("[ ");
let mut tags: MutMap<TagName, _> = MutMap::default(); let mut tags: MutMap<TagName, _> = MutMap::default();
tags.insert(*tag_name.clone(), vec![]); tags.insert(subs[*tag_name].clone(), vec![]);
let ext_content = write_sorted_tags(env, subs, buf, &tags, *ext_var); let ext_content = write_sorted_tags(env, subs, buf, &tags, *ext_var);
buf.push_str(" ]"); buf.push_str(" ]");
@ -562,7 +562,7 @@ pub fn chase_ext_tag_union<'a>(
chase_ext_tag_union(subs, *ext_var, fields) chase_ext_tag_union(subs, *ext_var, fields)
} }
Content::Structure(FunctionOrTagUnion(tag_name, _, ext_var)) => { Content::Structure(FunctionOrTagUnion(tag_name, _, ext_var)) => {
fields.push((*tag_name.clone(), vec![])); fields.push((subs[*tag_name].clone(), vec![]));
chase_ext_tag_union(subs, *ext_var, fields) chase_ext_tag_union(subs, *ext_var, fields)
} }

View file

@ -437,7 +437,7 @@ impl SolvedType {
FunctionOrTagUnion(tag_name, symbol, ext_var) => { FunctionOrTagUnion(tag_name, symbol, ext_var) => {
let ext = Self::from_var_help(subs, recursion_vars, *ext_var); let ext = Self::from_var_help(subs, recursion_vars, *ext_var);
SolvedType::FunctionOrTagUnion(*tag_name.clone(), *symbol, Box::new(ext)) SolvedType::FunctionOrTagUnion(subs[*tag_name].clone(), *symbol, Box::new(ext))
} }
RecursiveTagUnion(rec_var, tags, ext_var) => { RecursiveTagUnion(rec_var, tags, ext_var) => {
recursion_vars.insert(subs, *rec_var); recursion_vars.insert(subs, *rec_var);

View file

@ -100,6 +100,20 @@ impl std::ops::Index<SubsIndex<Lowercase>> for Subs {
} }
} }
impl std::ops::Index<SubsIndex<TagName>> for Subs {
type Output = TagName;
fn index(&self, index: SubsIndex<TagName>) -> &Self::Output {
&self.tag_names[index.start as usize]
}
}
impl std::ops::IndexMut<SubsIndex<TagName>> for Subs {
fn index_mut(&mut self, index: SubsIndex<TagName>) -> &mut Self::Output {
&mut self.tag_names[index.start as usize]
}
}
impl std::ops::IndexMut<SubsIndex<Lowercase>> for Subs { impl std::ops::IndexMut<SubsIndex<Lowercase>> for Subs {
fn index_mut(&mut self, index: SubsIndex<Lowercase>) -> &mut Self::Output { fn index_mut(&mut self, index: SubsIndex<Lowercase>) -> &mut Self::Output {
&mut self.field_names[index.start as usize] &mut self.field_names[index.start as usize]
@ -833,7 +847,7 @@ pub enum FlatType {
Func(VariableSubsSlice, Variable, Variable), Func(VariableSubsSlice, Variable, Variable),
Record(RecordFields, Variable), Record(RecordFields, Variable),
TagUnion(MutMap<TagName, Vec<Variable>>, Variable), TagUnion(MutMap<TagName, Vec<Variable>>, Variable),
FunctionOrTagUnion(Box<TagName>, Symbol, Variable), FunctionOrTagUnion(SubsIndex<TagName>, Symbol, Variable),
RecursiveTagUnion(Variable, MutMap<TagName, Vec<Variable>>, Variable), RecursiveTagUnion(Variable, MutMap<TagName, Vec<Variable>>, Variable),
Erroneous(Box<Problem>), Erroneous(Box<Problem>),
EmptyRecord, EmptyRecord,
@ -1661,7 +1675,7 @@ fn flat_type_to_err_type(
} }
FunctionOrTagUnion(tag_name, _, ext_var) => { FunctionOrTagUnion(tag_name, _, ext_var) => {
let tag_name = *tag_name; let tag_name = subs[tag_name].clone();
let mut err_tags = SendMap::default(); let mut err_tags = SendMap::default();

View file

@ -3,8 +3,8 @@ use roc_module::ident::{Lowercase, TagName};
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use roc_types::subs::Content::{self, *}; use roc_types::subs::Content::{self, *};
use roc_types::subs::{ use roc_types::subs::{
Descriptor, FlatType, GetSubsSlice, Mark, OptVariable, RecordFields, Subs, SubsSlice, Variable, Descriptor, FlatType, GetSubsSlice, Mark, OptVariable, RecordFields, Subs, SubsIndex,
VariableSubsSlice, SubsSlice, Variable, VariableSubsSlice,
}; };
use roc_types::types::{ErrorType, Mismatch, RecordField}; use roc_types::types::{ErrorType, Mismatch, RecordField};
@ -1252,6 +1252,9 @@ fn unify_flat_type(
) )
} }
(FunctionOrTagUnion(tag_name_1, _, ext_1), FunctionOrTagUnion(tag_name_2, _, ext_2)) => { (FunctionOrTagUnion(tag_name_1, _, ext_1), FunctionOrTagUnion(tag_name_2, _, ext_2)) => {
let tag_name_1 = subs[*tag_name_1].clone();
let tag_name_2 = subs[*tag_name_2].clone();
if tag_name_1 == tag_name_2 { if tag_name_1 == tag_name_2 {
let problems = unify_pool(subs, pool, *ext_1, *ext_2); let problems = unify_pool(subs, pool, *ext_1, *ext_2);
if problems.is_empty() { if problems.is_empty() {
@ -1262,28 +1265,30 @@ fn unify_flat_type(
} }
} else { } else {
let mut tags1 = MutMap::default(); let mut tags1 = MutMap::default();
tags1.insert(*tag_name_1.clone(), vec![]); tags1.insert(tag_name_1.clone(), vec![]);
let union1 = gather_tags(subs, tags1, *ext_1); let union1 = gather_tags(subs, tags1, *ext_1);
let mut tags2 = MutMap::default(); let mut tags2 = MutMap::default();
tags2.insert(*tag_name_2.clone(), vec![]); tags2.insert(tag_name_2.clone(), vec![]);
let union2 = gather_tags(subs, tags2, *ext_2); let union2 = gather_tags(subs, tags2, *ext_2);
unify_tag_union(subs, pool, ctx, union1, union2, (None, None)) unify_tag_union(subs, pool, ctx, union1, union2, (None, None))
} }
} }
(TagUnion(tags1, ext1), FunctionOrTagUnion(tag_name, _, ext2)) => { (TagUnion(tags1, ext1), FunctionOrTagUnion(tag_name, _, ext2)) => {
let tag_name = subs[*tag_name].clone();
let union1 = gather_tags(subs, tags1.clone(), *ext1); let union1 = gather_tags(subs, tags1.clone(), *ext1);
let mut tags2 = MutMap::default(); let mut tags2 = MutMap::default();
tags2.insert(*tag_name.clone(), vec![]); tags2.insert(tag_name.clone(), vec![]);
let union2 = gather_tags(subs, tags2, *ext2); let union2 = gather_tags(subs, tags2, *ext2);
unify_tag_union(subs, pool, ctx, union1, union2, (None, None)) unify_tag_union(subs, pool, ctx, union1, union2, (None, None))
} }
(FunctionOrTagUnion(tag_name, _, ext1), TagUnion(tags2, ext2)) => { (FunctionOrTagUnion(tag_name, _, ext1), TagUnion(tags2, ext2)) => {
let tag_name = subs[*tag_name].clone();
let mut tags1 = MutMap::default(); let mut tags1 = MutMap::default();
tags1.insert(*tag_name.clone(), vec![]); tags1.insert(tag_name.clone(), vec![]);
let union1 = gather_tags(subs, tags1, *ext1); let union1 = gather_tags(subs, tags1, *ext1);
let union2 = gather_tags(subs, tags2.clone(), *ext2); let union2 = gather_tags(subs, tags2.clone(), *ext2);
@ -1295,8 +1300,10 @@ fn unify_flat_type(
// this never happens in type-correct programs, but may happen if there is a type error // this never happens in type-correct programs, but may happen if there is a type error
debug_assert!(is_recursion_var(subs, *recursion_var)); debug_assert!(is_recursion_var(subs, *recursion_var));
let tag_name = subs[*tag_name].clone();
let mut tags2 = MutMap::default(); let mut tags2 = MutMap::default();
tags2.insert(*tag_name.clone(), vec![]); tags2.insert(tag_name.clone(), vec![]);
let union1 = gather_tags(subs, tags1.clone(), *ext1); let union1 = gather_tags(subs, tags1.clone(), *ext1);
let union2 = gather_tags(subs, tags2, *ext2); let union2 = gather_tags(subs, tags2, *ext2);
@ -1314,8 +1321,10 @@ fn unify_flat_type(
(FunctionOrTagUnion(tag_name, _, ext1), RecursiveTagUnion(recursion_var, tags2, ext2)) => { (FunctionOrTagUnion(tag_name, _, ext1), RecursiveTagUnion(recursion_var, tags2, ext2)) => {
debug_assert!(is_recursion_var(subs, *recursion_var)); debug_assert!(is_recursion_var(subs, *recursion_var));
let tag_name = subs[*tag_name].clone();
let mut tags1 = MutMap::default(); let mut tags1 = MutMap::default();
tags1.insert(*tag_name.clone(), vec![]); tags1.insert(tag_name.clone(), vec![]);
let union1 = gather_tags(subs, tags1, *ext1); let union1 = gather_tags(subs, tags1, *ext1);
let union2 = gather_tags(subs, tags2.clone(), *ext2); let union2 = gather_tags(subs, tags2.clone(), *ext2);
@ -1536,7 +1545,7 @@ fn unify_function_or_tag_union_and_func(
subs: &mut Subs, subs: &mut Subs,
pool: &mut Pool, pool: &mut Pool,
ctx: &Context, ctx: &Context,
tag_name: &TagName, tag_name_index: &SubsIndex<TagName>,
tag_symbol: Symbol, tag_symbol: Symbol,
tag_ext: Variable, tag_ext: Variable,
function_arguments: VariableSubsSlice, function_arguments: VariableSubsSlice,
@ -1546,6 +1555,8 @@ fn unify_function_or_tag_union_and_func(
) -> Outcome { ) -> Outcome {
use FlatType::*; use FlatType::*;
let tag_name = subs[*tag_name_index].clone();
let mut new_tags = MutMap::with_capacity_and_hasher(1, default_hasher()); let mut new_tags = MutMap::with_capacity_and_hasher(1, default_hasher());
new_tags.insert( new_tags.insert(