use get_content_without_compacting more

This commit is contained in:
Folkert 2021-07-30 22:15:17 +02:00
parent 4be163fc98
commit 35404bd25f
14 changed files with 203 additions and 209 deletions

View File

@ -324,9 +324,9 @@ fn jit_to_ast_help<'a>(
todo!("print recursive tag unions in the REPL")
}
Content::Alias(_, _, actual) => {
let content = env.subs.get_without_compacting(*actual).content;
let content = env.subs.get_content_without_compacting(*actual);
jit_to_ast_help(env, lib, main_fn_name, layout, &content)
jit_to_ast_help(env, lib, main_fn_name, layout, content)
}
other => unreachable!("Weird content for Union layout: {:?}", other),
}
@ -468,7 +468,7 @@ fn list_to_ast<'a>(
let elem_var = *vars.first().unwrap();
env.subs.get_without_compacting(elem_var).content
env.subs.get_content_without_compacting(elem_var)
}
other => {
unreachable!(
@ -486,7 +486,7 @@ fn list_to_ast<'a>(
let offset_bytes = index * elem_size;
let elem_ptr = unsafe { ptr.add(offset_bytes) };
let loc_expr = &*arena.alloc(Located {
value: ptr_to_ast(env, elem_ptr, elem_layout, &elem_content),
value: ptr_to_ast(env, elem_ptr, elem_layout, elem_content),
region: Region::zero(),
});
@ -539,8 +539,8 @@ where
let mut field_ptr = ptr as *const u8;
for (var, layout) in sequence {
let content = subs.get_without_compacting(var).content;
let expr = ptr_to_ast(env, field_ptr, layout, &content);
let content = subs.get_content_without_compacting(var);
let expr = ptr_to_ast(env, field_ptr, layout, content);
let loc_expr = Located::at_zero(expr);
output.push(&*arena.alloc(loc_expr));
@ -577,10 +577,10 @@ fn struct_to_ast<'a>(
// this is a 1-field wrapper record around another record or 1-tag tag union
let (label, field) = sorted_fields.pop().unwrap();
let inner_content = env.subs.get_without_compacting(field.into_inner()).content;
let inner_content = env.subs.get_content_without_compacting(field.into_inner());
let loc_expr = &*arena.alloc(Located {
value: ptr_to_ast(env, ptr, &Layout::Struct(field_layouts), &inner_content),
value: ptr_to_ast(env, ptr, &Layout::Struct(field_layouts), inner_content),
region: Region::zero(),
});
@ -606,9 +606,9 @@ fn struct_to_ast<'a>(
let mut field_ptr = ptr;
for ((label, field), field_layout) in sorted_fields.iter().zip(field_layouts.iter()) {
let content = subs.get_without_compacting(*field.as_inner()).content;
let content = subs.get_content_without_compacting(*field.as_inner());
let loc_expr = &*arena.alloc(Located {
value: ptr_to_ast(env, field_ptr, field_layout, &content),
value: ptr_to_ast(env, field_ptr, field_layout, content),
region: Region::zero(),
});
@ -659,9 +659,9 @@ fn bool_to_ast<'a>(env: &Env<'a, '_>, value: bool, content: &Content) -> Expr<'a
// and/or records (e.g. { a: { b: { c: True } } }),
// so we need to do this recursively on the field type.
let field_var = *field.as_inner();
let field_content = env.subs.get_without_compacting(field_var).content;
let field_content = env.subs.get_content_without_compacting(field_var);
let loc_expr = Located {
value: bool_to_ast(env, value, &field_content),
value: bool_to_ast(env, value, field_content),
region: Region::zero(),
};
@ -701,10 +701,10 @@ fn bool_to_ast<'a>(env: &Env<'a, '_>, value: bool, content: &Content) -> Expr<'a
debug_assert_eq!(payload_vars.len(), 1);
let var = *payload_vars.iter().next().unwrap();
let content = env.subs.get_without_compacting(var).content;
let content = env.subs.get_content_without_compacting(var);
let loc_payload = &*arena.alloc(Located {
value: bool_to_ast(env, value, &content),
value: bool_to_ast(env, value, content),
region: Region::zero(),
});
@ -739,9 +739,9 @@ fn bool_to_ast<'a>(env: &Env<'a, '_>, value: bool, content: &Content) -> Expr<'a
}
}
Alias(_, _, var) => {
let content = env.subs.get_without_compacting(*var).content;
let content = env.subs.get_content_without_compacting(*var);
bool_to_ast(env, value, &content)
bool_to_ast(env, value, content)
}
other => {
unreachable!("Unexpected FlatType {:?} in bool_to_ast", other);
@ -771,9 +771,9 @@ fn byte_to_ast<'a>(env: &Env<'a, '_>, value: u8, content: &Content) -> Expr<'a>
// and/or records (e.g. { a: { b: { c: True } } }),
// so we need to do this recursively on the field type.
let field_var = *field.as_inner();
let field_content = env.subs.get_without_compacting(field_var).content;
let field_content = env.subs.get_content_without_compacting(field_var);
let loc_expr = Located {
value: byte_to_ast(env, value, &field_content),
value: byte_to_ast(env, value, field_content),
region: Region::zero(),
};
@ -813,10 +813,10 @@ fn byte_to_ast<'a>(env: &Env<'a, '_>, value: u8, content: &Content) -> Expr<'a>
debug_assert_eq!(payload_vars.len(), 1);
let var = *payload_vars.iter().next().unwrap();
let content = env.subs.get_without_compacting(var).content;
let content = env.subs.get_content_without_compacting(var);
let loc_payload = &*arena.alloc(Located {
value: byte_to_ast(env, value, &content),
value: byte_to_ast(env, value, content),
region: Region::zero(),
});
@ -850,9 +850,9 @@ fn byte_to_ast<'a>(env: &Env<'a, '_>, value: u8, content: &Content) -> Expr<'a>
}
}
Alias(_, _, var) => {
let content = env.subs.get_without_compacting(*var).content;
let content = env.subs.get_content_without_compacting(*var);
byte_to_ast(env, value, &content)
byte_to_ast(env, value, content)
}
other => {
unreachable!("Unexpected FlatType {:?} in bool_to_ast", other);
@ -887,9 +887,9 @@ fn num_to_ast<'a>(env: &Env<'a, '_>, num_expr: Expr<'a>, content: &Content) -> E
// and/or records (e.g. { a: { b: { c: 5 } } }),
// so we need to do this recursively on the field type.
let field_var = *field.as_inner();
let field_content = env.subs.get_without_compacting(field_var).content;
let field_content = env.subs.get_content_without_compacting(field_var);
let loc_expr = Located {
value: num_to_ast(env, num_expr, &field_content),
value: num_to_ast(env, num_expr, field_content),
region: Region::zero(),
};
@ -937,10 +937,10 @@ fn num_to_ast<'a>(env: &Env<'a, '_>, num_expr: Expr<'a>, content: &Content) -> E
debug_assert_eq!(payload_vars.len(), 1);
let var = *payload_vars.iter().next().unwrap();
let content = env.subs.get_without_compacting(var).content;
let content = env.subs.get_content_without_compacting(var);
let loc_payload = &*arena.alloc(Located {
value: num_to_ast(env, num_expr, &content),
value: num_to_ast(env, num_expr, content),
region: Region::zero(),
});
@ -955,9 +955,9 @@ fn num_to_ast<'a>(env: &Env<'a, '_>, num_expr: Expr<'a>, content: &Content) -> E
}
}
Alias(_, _, var) => {
let content = env.subs.get_without_compacting(*var).content;
let content = env.subs.get_content_without_compacting(*var);
num_to_ast(env, num_expr, &content)
num_to_ast(env, num_expr, content)
}
other => {
panic!("Unexpected FlatType {:?} in num_to_ast", other);

View File

@ -154,8 +154,8 @@ pub fn gen_and_eval<'a>(
// pretty-print the expr type string for later.
name_all_type_vars(main_fn_var, &mut subs);
let content = subs.get(main_fn_var).content;
let expr_type_str = content_to_string(content.clone(), &subs, home, &interns);
let content = subs.get_content_without_compacting(main_fn_var);
let expr_type_str = content_to_string(content, &subs, home, &interns);
let (_, main_fn_layout) = match procedures.keys().find(|(s, _)| *s == main_fn_symbol) {
Some(layout) => *layout,
@ -227,7 +227,7 @@ pub fn gen_and_eval<'a>(
lib,
main_fn_name,
main_fn_layout,
&content,
content,
&env.interns,
home,
&subs,

View File

@ -184,10 +184,9 @@ mod test_load {
expected_types: &mut HashMap<&str, &str>,
) {
for (symbol, expr_var) in &def.pattern_vars {
let content = subs.get(*expr_var).content;
name_all_type_vars(*expr_var, subs);
let content = subs.get_content_without_compacting(*expr_var);
let actual_str = content_to_string(content, subs, home, interns);
let fully_qualified = symbol.fully_qualified(interns, home).to_string();
let expected_type = expected_types

View File

@ -3010,7 +3010,7 @@ pub fn with_hole<'a>(
let arena = env.arena;
debug_assert!(!matches!(
env.subs.get_without_compacting(variant_var).content,
env.subs.get_content_without_compacting(variant_var),
Content::Structure(FlatType::Func(_, _, _))
));
convert_tag_union(
@ -3035,12 +3035,15 @@ pub fn with_hole<'a>(
} => {
let arena = env.arena;
let desc = env.subs.get_without_compacting(variant_var);
let content = env.subs.get_content_without_compacting(variant_var);
if let Content::Structure(FlatType::Func(arg_vars, _, ret_var)) = content {
let ret_var = *ret_var;
let arg_vars = arg_vars.clone();
if let Content::Structure(FlatType::Func(arg_vars, _, ret_var)) = desc.content {
tag_union_to_function(
env,
arg_vars,
&arg_vars,
ret_var,
tag_name,
closure_name,
@ -4343,7 +4346,7 @@ fn convert_tag_union<'a>(
#[allow(clippy::too_many_arguments)]
fn tag_union_to_function<'a>(
env: &mut Env<'a, '_>,
argument_variables: std::vec::Vec<Variable>,
argument_variables: &[Variable],
return_variable: Variable,
tag_name: TagName,
proc_symbol: Symbol,
@ -4364,8 +4367,8 @@ fn tag_union_to_function<'a>(
let loc_expr = Located::at_zero(roc_can::expr::Expr::Var(arg_symbol));
loc_pattern_args.push((arg_var, loc_pattern));
loc_expr_args.push((arg_var, loc_expr));
loc_pattern_args.push((*arg_var, loc_pattern));
loc_expr_args.push((*arg_var, loc_expr));
}
let loc_body = Located::at_zero(roc_can::expr::Expr::Tag {
@ -7395,8 +7398,8 @@ fn from_can_pattern_help<'a>(
// TODO these don't match up in the uniqueness inference; when we remove
// that, reinstate this assert!
//
// dbg!(&env.subs.get_without_compacting(*field_var).content);
// dbg!(&env.subs.get_without_compacting(destruct.value.var).content);
// dbg!(&env.subs.get_content_without_compacting(*field_var));
// dbg!(&env.subs.get_content_without_compacting(destruct.var).content);
// debug_assert_eq!(
// env.subs.get_root_key_without_compacting(*field_var),
// env.subs.get_root_key_without_compacting(destruct.value.var)
@ -7490,7 +7493,7 @@ pub fn num_argument_to_int_or_float(
var: Variable,
known_to_be_float: bool,
) -> IntOrFloat {
match subs.get_without_compacting(var).content {
match subs.get_content_without_compacting(var){
Content::FlexVar(_) | Content::RigidVar(_) if known_to_be_float => IntOrFloat::BinaryFloatType(FloatPrecision::F64),
Content::FlexVar(_) | Content::RigidVar(_) => IntOrFloat::SignedIntType(IntPrecision::I64), // We default (Num *) to I64

View File

@ -36,7 +36,10 @@ pub fn infer_expr(
};
let (solved, _) = solve::run(&env, problems, subs, constraint);
let content = solved.inner().get_without_compacting(expr_var).content;
let content = solved
.inner()
.get_content_without_compacting(expr_var)
.clone();
(content, solved.into_inner())
}

View File

@ -528,11 +528,10 @@ fn solve(
.get(next_rank)
.iter()
.filter(|var| {
let current = subs.get_without_compacting(
roc_types::subs::Variable::clone(var),
);
let current_rank =
subs.get_rank(roc_types::subs::Variable::clone(var));
current.rank.into_usize() > next_rank.into_usize()
current_rank.into_usize() > next_rank.into_usize()
})
.collect::<Vec<_>>();
@ -561,8 +560,7 @@ fn solve(
let failing: Vec<_> = rigid_vars
.iter()
.filter(|&var| {
!subs.redundant(*var)
&& subs.get_without_compacting(*var).rank != Rank::NONE
!subs.redundant(*var) && subs.get_rank(*var) != Rank::NONE
})
.collect();

View File

@ -115,7 +115,7 @@ mod solve_expr {
let content = {
debug_assert!(exposed_to_host.len() == 1);
let (_symbol, variable) = exposed_to_host.into_iter().next().unwrap();
subs.get(variable).content
subs.get_content_without_compacting(variable)
};
let actual_str = content_to_string(content, subs, home, &interns);

View File

@ -77,7 +77,7 @@ fn find_names_needed(
use crate::subs::FlatType::*;
while let Some((recursive, _chain)) = subs.occurs(variable) {
let content = subs.get_without_compacting(recursive).content;
let content = subs.get_content_without_compacting(recursive).clone();
match content {
Content::Structure(FlatType::TagUnion(tags, ext_var)) => {
let rec_var = subs.fresh_unnamed_flex_var();
@ -104,7 +104,7 @@ fn find_names_needed(
}
}
match subs.get_without_compacting(variable).content {
match &subs.get_content_without_compacting(variable).clone() {
RecursionVar { opt_name: None, .. } | FlexVar(None) => {
let root = subs.get_root_key_without_compacting(variable);
@ -133,24 +133,24 @@ fn find_names_needed(
// User-defined names are already taken.
// We must not accidentally generate names that collide with them!
names_taken.insert(name);
names_taken.insert(name.clone());
}
RigidVar(name) => {
// User-defined names are already taken.
// We must not accidentally generate names that collide with them!
names_taken.insert(name);
names_taken.insert(name.clone());
}
Structure(Apply(_, args)) => {
for var in args {
find_names_needed(var, subs, roots, root_appearances, names_taken);
find_names_needed(*var, subs, roots, root_appearances, names_taken);
}
}
Structure(Func(arg_vars, _closure_var, ret_var)) => {
for var in arg_vars {
find_names_needed(var, subs, roots, root_appearances, names_taken);
find_names_needed(*var, subs, roots, root_appearances, names_taken);
}
find_names_needed(ret_var, subs, roots, root_appearances, names_taken);
find_names_needed(*ret_var, subs, roots, root_appearances, names_taken);
}
Structure(Record(fields, ext_var)) => {
let mut sorted_fields: Vec<_> = fields.iter().collect();
@ -167,7 +167,7 @@ fn find_names_needed(
);
}
find_names_needed(ext_var, subs, roots, root_appearances, names_taken);
find_names_needed(*ext_var, subs, roots, root_appearances, names_taken);
}
Structure(TagUnion(tags, ext_var)) => {
let mut sorted_tags: Vec<_> = tags.iter().collect();
@ -177,10 +177,10 @@ fn find_names_needed(
find_names_needed(*var, subs, roots, root_appearances, names_taken);
}
find_names_needed(ext_var, subs, roots, root_appearances, names_taken);
find_names_needed(*ext_var, subs, roots, root_appearances, names_taken);
}
Structure(FunctionOrTagUnion(_, _, ext_var)) => {
find_names_needed(ext_var, subs, roots, root_appearances, names_taken);
find_names_needed(*ext_var, subs, roots, root_appearances, names_taken);
}
Structure(RecursiveTagUnion(rec_var, tags, ext_var)) => {
let mut sorted_tags: Vec<_> = tags.iter().collect();
@ -190,12 +190,12 @@ fn find_names_needed(
find_names_needed(*var, subs, roots, root_appearances, names_taken);
}
find_names_needed(ext_var, subs, roots, root_appearances, names_taken);
find_names_needed(rec_var, subs, roots, root_appearances, names_taken);
find_names_needed(*ext_var, subs, roots, root_appearances, names_taken);
find_names_needed(*rec_var, subs, roots, root_appearances, names_taken);
}
Alias(_symbol, args, _actual) => {
for (_, var) in args {
find_names_needed(var, subs, roots, root_appearances, names_taken);
find_names_needed(*var, subs, roots, root_appearances, names_taken);
}
// TODO should we also look in the actual variable?
// find_names_needed(_actual, subs, roots, root_appearances, names_taken);
@ -240,22 +240,22 @@ fn name_root(
fn set_root_name(root: Variable, name: Lowercase, subs: &mut Subs) {
use crate::subs::Content::*;
let mut descriptor = subs.get_without_compacting(root);
let old_content = subs.get_content_without_compacting(root);
match descriptor.content {
match old_content {
FlexVar(None) => {
descriptor.content = FlexVar(Some(name));
subs.set(root, descriptor);
let content = FlexVar(Some(name));
subs.set_content(root, content);
}
RecursionVar {
opt_name: None,
structure,
} => {
descriptor.content = RecursionVar {
structure,
let content = RecursionVar {
structure: *structure,
opt_name: Some(name),
};
subs.set(root, descriptor);
subs.set_content(root, content);
}
RecursionVar {
opt_name: Some(_existing),
@ -270,7 +270,7 @@ fn set_root_name(root: Variable, name: Lowercase, subs: &mut Subs) {
}
pub fn content_to_string(
content: Content,
content: &Content,
subs: &Subs,
home: ModuleId,
interns: &Interns,
@ -283,7 +283,7 @@ pub fn content_to_string(
buf
}
fn write_content(env: &Env, content: Content, subs: &Subs, buf: &mut String, parens: Parens) {
fn write_content(env: &Env, content: &Content, subs: &Subs, buf: &mut String, parens: Parens) {
use crate::subs::Content::*;
match content {
@ -298,14 +298,14 @@ fn write_content(env: &Env, content: Content, subs: &Subs, buf: &mut String, par
Alias(symbol, args, _actual) => {
let write_parens = parens == Parens::InTypeParam && !args.is_empty();
match symbol {
match *symbol {
Symbol::NUM_NUM => {
debug_assert_eq!(args.len(), 1);
let (_, arg_var) = args
.get(0)
.expect("Num was not applied to a type argument!");
let content = subs.get_without_compacting(*arg_var).content;
let content = subs.get_content_without_compacting(*arg_var);
match &content {
Alias(nested, _, _) => match *nested {
@ -326,13 +326,13 @@ fn write_content(env: &Env, content: Content, subs: &Subs, buf: &mut String, par
}
_ => write_parens!(write_parens, buf, {
write_symbol(env, symbol, buf);
write_symbol(env, *symbol, buf);
for (_, var) in args {
buf.push(' ');
write_content(
env,
subs.get_without_compacting(var).content,
subs.get_content_without_compacting(*var),
subs,
buf,
Parens::InTypeParam,
@ -342,7 +342,7 @@ fn write_content(env: &Env, content: Content, subs: &Subs, buf: &mut String, par
// useful for debugging
if false {
buf.push_str("[[ but really ");
let content = subs.get_without_compacting(_actual).content;
let content = subs.get_content_without_compacting(*_actual);
write_content(env, content, subs, buf, parens);
buf.push_str("]]");
}
@ -353,19 +353,77 @@ fn write_content(env: &Env, content: Content, subs: &Subs, buf: &mut String, par
}
}
fn write_flat_type(env: &Env, flat_type: FlatType, subs: &Subs, buf: &mut String, parens: Parens) {
fn write_sorted_tags(
env: &Env,
subs: &Subs,
buf: &mut String,
tags: &MutMap<TagName, Vec<Variable>>,
ext_var: Variable,
) -> Result<(), (Variable, Content)> {
// Sort the fields so they always end up in the same order.
let mut sorted_fields = Vec::with_capacity(tags.len());
for (label, vars) in tags {
sorted_fields.push((label.clone(), vars));
}
// If the `ext` contains tags, merge them into the list of tags.
// this can occur when inferring mutually recursive tags
let mut from_ext = Default::default();
let ext_content = chase_ext_tag_union(subs, ext_var, &mut from_ext);
for (tag_name, arguments) in from_ext.iter() {
sorted_fields.push((tag_name.clone(), arguments));
}
let interns = &env.interns;
let home = env.home;
sorted_fields.sort_by(|(a, _), (b, _)| {
a.clone()
.as_string(interns, home)
.cmp(&b.as_string(interns, home))
});
let mut any_written_yet = false;
for (label, vars) in sorted_fields {
if any_written_yet {
buf.push_str(", ");
} else {
any_written_yet = true;
}
buf.push_str(&label.as_string(interns, home));
for var in vars {
buf.push(' ');
write_content(
env,
subs.get_content_without_compacting(*var),
subs,
buf,
Parens::InTypeParam,
);
}
}
ext_content
}
fn write_flat_type(env: &Env, flat_type: &FlatType, subs: &Subs, buf: &mut String, parens: Parens) {
use crate::subs::FlatType::*;
match flat_type {
Apply(symbol, args) => write_apply(env, symbol, args, subs, buf, parens),
Apply(symbol, args) => write_apply(env, *symbol, args, subs, buf, parens),
EmptyRecord => buf.push_str(EMPTY_RECORD),
EmptyTagUnion => buf.push_str(EMPTY_TAG_UNION),
Func(args, _closure, ret) => write_fn(env, args, ret, subs, buf, parens),
Func(args, _closure, ret) => write_fn(env, args, *ret, subs, buf, parens),
Record(fields, ext_var) => {
use crate::types::{gather_fields, RecordStructure};
// If the `ext` has concrete fields (e.g. { foo : I64}{ bar : Bool }), merge them
let RecordStructure { fields, ext } = gather_fields(subs, fields, ext_var);
let RecordStructure { fields, ext } = gather_fields(subs, fields, *ext_var);
let ext_var = ext;
if fields.is_empty() {
@ -408,7 +466,7 @@ fn write_flat_type(env: &Env, flat_type: FlatType, subs: &Subs, buf: &mut String
write_content(
env,
subs.get_without_compacting(var).content,
subs.get_content_without_compacting(var),
subs,
buf,
Parens::Unnecessary,
@ -418,7 +476,7 @@ fn write_flat_type(env: &Env, flat_type: FlatType, subs: &Subs, buf: &mut String
buf.push_str(" }");
}
match subs.get_without_compacting(ext_var).content {
match subs.get_content_without_compacting(ext_var) {
Content::Structure(EmptyRecord) => {
// This is a closed record. We're done!
}
@ -433,50 +491,9 @@ fn write_flat_type(env: &Env, flat_type: FlatType, subs: &Subs, buf: &mut String
}
}
TagUnion(tags, ext_var) => {
let interns = &env.interns;
let home = env.home;
buf.push_str("[ ");
// Sort the fields so they always end up in the same order.
let mut sorted_fields = Vec::with_capacity(tags.len());
for (label, vars) in tags {
sorted_fields.push((label.clone(), vars));
}
// If the `ext` contains tags, merge them into the list of tags.
// this can occur when inferring mutually recursive tags
let ext_content = chase_ext_tag_union(subs, ext_var, &mut sorted_fields);
sorted_fields.sort_by(|(a, _), (b, _)| {
a.clone()
.as_string(interns, home)
.cmp(&b.as_string(interns, home))
});
let mut any_written_yet = false;
for (label, vars) in sorted_fields {
if any_written_yet {
buf.push_str(", ");
} else {
any_written_yet = true;
}
buf.push_str(&label.as_string(interns, home));
for var in vars {
buf.push(' ');
write_content(
env,
subs.get_without_compacting(var).content,
subs,
buf,
Parens::InTypeParam,
);
}
}
let ext_content = write_sorted_tags(env, subs, buf, tags, *ext_var);
buf.push_str(" ]");
@ -486,72 +503,33 @@ fn write_flat_type(env: &Env, flat_type: FlatType, subs: &Subs, buf: &mut String
//
// e.g. the "*" at the end of `{ x: I64 }*`
// or the "r" at the end of `{ x: I64 }r`
write_content(env, content, subs, buf, parens)
write_content(env, &content, subs, buf, parens)
}
}
FunctionOrTagUnion(tag_name, _, ext_var) => {
let interns = &env.interns;
let home = env.home;
buf.push_str("[ ");
buf.push_str(&tag_name.as_string(interns, home));
let mut tags = MutMap::default();
tags.insert(tag_name.clone(), vec![]);
let ext_content = write_sorted_tags(env, subs, buf, &tags, *ext_var);
buf.push_str(" ]");
let mut sorted_fields = vec![(tag_name, vec![])];
let ext_content = chase_ext_tag_union(subs, ext_var, &mut sorted_fields);
if let Err((_, content)) = ext_content {
// This is an open tag union, so print the variable
// right after the ']'
//
// e.g. the "*" at the end of `{ x: I64 }*`
// or the "r" at the end of `{ x: I64 }r`
write_content(env, content, subs, buf, parens)
write_content(env, &content, subs, buf, parens)
}
}
RecursiveTagUnion(rec_var, tags, ext_var) => {
let interns = &env.interns;
let home = env.home;
buf.push_str("[ ");
// Sort the fields so they always end up in the same order.
let mut sorted_fields = Vec::with_capacity(tags.len());
for (label, vars) in tags {
sorted_fields.push((label.clone(), vars));
}
// If the `ext` contains tags, merge them into the list of tags.
// this can occur when inferring mutually recursive tags
let ext_content = chase_ext_tag_union(subs, ext_var, &mut sorted_fields);
sorted_fields.sort_by(|(a, _), (b, _)| a.cmp(b));
let mut any_written_yet = false;
for (label, vars) in sorted_fields {
if any_written_yet {
buf.push_str(", ");
} else {
any_written_yet = true;
}
buf.push_str(&label.as_string(interns, home));
for var in vars {
buf.push(' ');
write_content(
env,
subs.get_without_compacting(var).content,
subs,
buf,
Parens::InTypeParam,
);
}
}
let ext_content = write_sorted_tags(env, subs, buf, tags, *ext_var);
buf.push_str(" ]");
@ -561,13 +539,13 @@ fn write_flat_type(env: &Env, flat_type: FlatType, subs: &Subs, buf: &mut String
//
// e.g. the "*" at the end of `{ x: I64 }*`
// or the "r" at the end of `{ x: I64 }r`
write_content(env, content, subs, buf, parens)
write_content(env, &content, subs, buf, parens)
}
buf.push_str(" as ");
write_content(
env,
subs.get_without_compacting(rec_var).content,
subs.get_content_without_compacting(*rec_var),
subs,
buf,
parens,
@ -614,25 +592,27 @@ pub fn chase_ext_record(
use crate::subs::Content::*;
use crate::subs::FlatType::*;
match subs.get_without_compacting(var).content {
match subs.get_content_without_compacting(var) {
Structure(Record(sub_fields, sub_ext)) => {
fields.extend(sub_fields.into_iter());
for (field_name, record_field) in sub_fields {
fields.insert(field_name.clone(), *record_field);
}
chase_ext_record(subs, sub_ext, fields)
chase_ext_record(subs, *sub_ext, fields)
}
Structure(EmptyRecord) => Ok(()),
Alias(_, _, var) => chase_ext_record(subs, var, fields),
Alias(_, _, var) => chase_ext_record(subs, *var, fields),
content => Err((var, content)),
content => Err((var, content.clone())),
}
}
fn write_apply(
env: &Env,
symbol: Symbol,
args: Vec<Variable>,
args: &[Variable],
subs: &Subs,
buf: &mut String,
parens: Parens,
@ -646,10 +626,10 @@ fn write_apply(
}
Symbol::NUM_NUM => {
let arg = args
.into_iter()
.iter()
.next()
.unwrap_or_else(|| panic!("Num did not have any type parameters somehow."));
let arg_content = subs.get_without_compacting(arg).content;
let arg_content = subs.get_content_without_compacting(*arg);
let mut arg_param = String::new();
let mut default_case = |subs, content| {
@ -690,7 +670,7 @@ fn write_apply(
buf.push(' ');
write_content(
env,
subs.get_without_compacting(arg).content,
subs.get_content_without_compacting(*arg),
subs,
buf,
Parens::InTypeParam,
@ -706,7 +686,7 @@ fn write_apply(
fn write_fn(
env: &Env,
args: Vec<Variable>,
args: &[Variable],
ret: Variable,
subs: &Subs,
buf: &mut String,
@ -728,7 +708,7 @@ fn write_fn(
write_content(
env,
subs.get_without_compacting(arg).content,
subs.get_content_without_compacting(*arg),
subs,
buf,
Parens::InFn,
@ -738,7 +718,7 @@ fn write_fn(
buf.push_str(" -> ");
write_content(
env,
subs.get_without_compacting(ret).content,
subs.get_content_without_compacting(ret),
subs,
buf,
Parens::InFn,

View File

@ -612,7 +612,7 @@ impl Content {
eprintln!(
"{}",
crate::pretty_print::content_to_string(self.clone(), subs, home, &interns)
crate::pretty_print::content_to_string(&self, subs, home, &interns)
);
self
@ -653,7 +653,7 @@ fn occurs(
if seen.contains(&root_var) {
Some((root_var, vec![]))
} else {
match subs.get_without_compacting(root_var).content {
match subs.get_content_without_compacting(root_var).clone() {
FlexVar(_) | RigidVar(_) | RecursionVar { .. } | Error => None,
Structure(flat_type) => {

View File

@ -1,7 +1,7 @@
use crate::pretty_print::Parens;
use crate::subs::{LambdaSet, Subs, VarStore, Variable};
use inlinable_string::InlinableString;
use roc_collections::all::{union, ImMap, ImSet, Index, MutMap, MutSet, SendMap};
use roc_collections::all::{ImMap, ImSet, Index, MutMap, MutSet, SendMap};
use roc_module::ident::{ForeignSymbol, Ident, Lowercase, TagName};
use roc_module::low_level::LowLevel;
use roc_module::symbol::{Interns, ModuleId, Symbol};
@ -1522,22 +1522,35 @@ pub fn name_type_var(letters_used: u32, taken: &mut MutSet<Lowercase>) -> (Lower
pub fn gather_fields(
subs: &Subs,
fields: MutMap<Lowercase, RecordField<Variable>>,
var: Variable,
other_fields: &MutMap<Lowercase, RecordField<Variable>>,
mut var: Variable,
) -> RecordStructure {
use crate::subs::Content::*;
use crate::subs::FlatType::*;
match subs.get_without_compacting(var).content {
Structure(Record(sub_fields, sub_ext)) => {
gather_fields(subs, union(fields, &sub_fields), sub_ext)
}
let mut result = other_fields.clone();
Alias(_, _, var) => {
// TODO according to elm/compiler: "TODO may be dropping useful alias info here"
gather_fields(subs, fields, var)
}
loop {
match subs.get_content_without_compacting(var) {
Structure(Record(sub_fields, sub_ext)) => {
for (lowercase, record_field) in sub_fields {
result.insert(lowercase.clone(), *record_field);
}
_ => RecordStructure { fields, ext: var },
var = *sub_ext;
}
Alias(_, _, actual_var) => {
// TODO according to elm/compiler: "TODO may be dropping useful alias info here"
var = *actual_var;
}
_ => break,
}
}
RecordStructure {
fields: result,
ext: var,
}
}

View File

@ -967,8 +967,8 @@ fn unify_flat_type(
}
(Record(fields1, ext1), Record(fields2, ext2)) => {
let rec1 = gather_fields(subs, fields1.clone(), *ext1);
let rec2 = gather_fields(subs, fields2.clone(), *ext2);
let rec1 = gather_fields(subs, fields1, *ext1);
let rec2 = gather_fields(subs, fields2, *ext2);
unify_record(subs, pool, ctx, rec1, rec2)
}

View File

@ -272,7 +272,7 @@ impl<'a> EdModel<'a> {
let subs = solved.inner_mut();
let content = subs.get(var).content;
let content = subs.get_content_without_compacting(var);
PoolStr::new(
&content_to_string(content, subs, self.module.env.home, self.interns),

View File

@ -565,11 +565,10 @@ fn solve<'a>(
.get(next_rank)
.iter()
.filter(|var| {
let current = subs.get_without_compacting(
roc_types::subs::Variable::clone(var),
);
let current_rank =
subs.get_rank(roc_types::subs::Variable::clone(var));
current.rank.into_usize() > next_rank.into_usize()
current_rank.into_usize() > next_rank.into_usize()
})
.collect::<Vec<_>>();
@ -598,8 +597,7 @@ fn solve<'a>(
let failing: Vec<_> = rigid_vars
.iter()
.filter(|&var| {
!subs.redundant(*var)
&& subs.get_without_compacting(*var).rank != Rank::NONE
!subs.redundant(*var) && subs.get_rank(*var) != Rank::NONE
})
.collect();

View File

@ -114,7 +114,7 @@ fn infer_eq(actual: &str, expected_str: &str) {
let subs = solved.inner_mut();
let content = subs.get(var).content;
let content = subs.get_content_without_compacting(var);
let interns = Interns {
module_ids: env.module_ids.clone(),