Remove references to multimorphic names

This commit is contained in:
Ayaz Hafiz 2022-07-01 16:05:49 -04:00 committed by ayazhafiz
parent 641bd95d04
commit a5ea4f8c11
No known key found for this signature in database
GPG key ID: B443F7A3030C9AED
10 changed files with 107 additions and 447 deletions

View file

@ -33,7 +33,7 @@ use roc_mono::ir::{
CapturedSymbols, EntryPoint, ExternalSpecializations, PartialProc, Proc, ProcLayout, Procs,
ProcsBase, UpdateModeIds,
};
use roc_mono::layout::{LambdaName, Layout, LayoutCache, LayoutProblem, MultimorphicNames};
use roc_mono::layout::{LambdaName, Layout, LayoutCache, LayoutProblem};
use roc_parse::ast::{self, Defs, ExtractSpaces, Spaced, StrLiteral, TypeAnnotation};
use roc_parse::header::{ExposedName, ImportsEntry, PackageEntry, PlatformHeader, To, TypedIdent};
use roc_parse::header::{HeaderFor, ModuleNameEnum, PackageName};
@ -428,7 +428,6 @@ fn start_phase<'a>(
exposed_to_host: state.exposed_to_host.clone(),
abilities_store,
derived_symbols,
multimorphic_names: state.multimorphic_names.clone(),
}
}
Phase::MakeSpecializations => {
@ -498,7 +497,6 @@ fn start_phase<'a>(
module_timing,
world_abilities: state.world_abilities.clone_ref(),
derived_symbols,
multimorphic_names: state.multimorphic_names.clone(),
}
}
}
@ -828,8 +826,6 @@ struct State<'a> {
pub render: RenderTarget,
pub multimorphic_names: MultimorphicNames,
/// All abilities across all modules.
pub world_abilities: WorldAbilities,
@ -880,7 +876,6 @@ impl<'a> State<'a> {
layout_caches: std::vec::Vec::with_capacity(number_of_workers),
cached_subs: Arc::new(Mutex::new(cached_subs)),
render,
multimorphic_names: MultimorphicNames::default(),
make_specializations_pass: MakeSpecializationsPass::Pass(1),
world_abilities: Default::default(),
}
@ -1005,7 +1000,6 @@ enum BuildTask<'a> {
exposed_to_host: ExposedToHost,
abilities_store: AbilitiesStore,
derived_symbols: GlobalDerivedSymbols,
multimorphic_names: MultimorphicNames,
},
MakeSpecializations {
module_id: ModuleId,
@ -1017,7 +1011,6 @@ enum BuildTask<'a> {
module_timing: ModuleTiming,
world_abilities: WorldAbilities,
derived_symbols: GlobalDerivedSymbols,
multimorphic_names: MultimorphicNames,
},
}
@ -2599,16 +2592,7 @@ fn finish_specialization(
.into_inner()
.into_module_ids();
let mut all_ident_ids = state.constrained_ident_ids;
let multimorphic_idents = state
.multimorphic_names
.try_unwrap_names()
.expect("There were still outstanding Arc references to multimorphic_names");
let old_idents = all_ident_ids.insert(ModuleId::MULTIMORPHIC, multimorphic_idents);
debug_assert!(
old_idents.is_none() || old_idents.unwrap().is_empty(),
"duplicate multimorphic idents"
);
let all_ident_ids = state.constrained_ident_ids;
let interns = Interns {
module_ids,
@ -4431,7 +4415,6 @@ fn make_specializations<'a>(
target_info: TargetInfo,
world_abilities: WorldAbilities,
derived_symbols: GlobalDerivedSymbols,
mut multimorphic_names: MultimorphicNames,
) -> Msg<'a> {
let make_specializations_start = SystemTime::now();
let mut update_mode_ids = UpdateModeIds::new();
@ -4447,7 +4430,6 @@ fn make_specializations<'a>(
call_specialization_counter: 1,
abilities: AbilitiesView::World(world_abilities),
derived_symbols: &derived_symbols,
multimorphic_names: &mut multimorphic_names,
};
let mut procs = Procs::new_in(arena);
@ -4511,7 +4493,6 @@ fn build_pending_specializations<'a>(
exposed_to_host: ExposedToHost, // TODO remove
abilities_store: AbilitiesStore,
derived_symbols: GlobalDerivedSymbols,
mut multimorphic_names: MultimorphicNames,
) -> Msg<'a> {
let find_specializations_start = SystemTime::now();
@ -4541,7 +4522,6 @@ fn build_pending_specializations<'a>(
// do we need a global view.
abilities: AbilitiesView::Module(&abilities_store),
derived_symbols: &derived_symbols,
multimorphic_names: &mut multimorphic_names,
};
// Add modules' decls to Procs
@ -4568,12 +4548,8 @@ fn build_pending_specializations<'a>(
// never gets called by Roc code, it will never
// get specialized!
if is_host_exposed {
let layout_result = layout_cache.raw_from_var(
mono_env.arena,
expr_var,
mono_env.subs,
mono_env.multimorphic_names,
);
let layout_result =
layout_cache.raw_from_var(mono_env.arena, expr_var, mono_env.subs);
// cannot specialize when e.g. main's type contains type variables
if let Err(e) = layout_result {
@ -4632,12 +4608,8 @@ fn build_pending_specializations<'a>(
// never gets called by Roc code, it will never
// get specialized!
if is_host_exposed {
let layout_result = layout_cache.raw_from_var(
mono_env.arena,
expr_var,
mono_env.subs,
mono_env.multimorphic_names,
);
let layout_result =
layout_cache.raw_from_var(mono_env.arena, expr_var, mono_env.subs);
// cannot specialize when e.g. main's type contains type variables
if let Err(e) = layout_result {
@ -4714,12 +4686,8 @@ fn build_pending_specializations<'a>(
// never gets called by Roc code, it will never
// get specialized!
if is_host_exposed {
let layout_result = layout_cache.raw_from_var(
mono_env.arena,
expr_var,
mono_env.subs,
mono_env.multimorphic_names,
);
let layout_result =
layout_cache.raw_from_var(mono_env.arena, expr_var, mono_env.subs);
// cannot specialize when e.g. main's type contains type variables
if let Err(e) = layout_result {
@ -4778,12 +4746,8 @@ fn build_pending_specializations<'a>(
// never gets called by Roc code, it will never
// get specialized!
if is_host_exposed {
let layout_result = layout_cache.raw_from_var(
mono_env.arena,
expr_var,
mono_env.subs,
mono_env.multimorphic_names,
);
let layout_result =
layout_cache.raw_from_var(mono_env.arena, expr_var, mono_env.subs);
// cannot specialize when e.g. main's type contains type variables
if let Err(e) = layout_result {
@ -4936,7 +4900,6 @@ fn run_task<'a>(
exposed_to_host,
abilities_store,
derived_symbols,
multimorphic_names,
} => Ok(build_pending_specializations(
arena,
solved_subs,
@ -4950,7 +4913,6 @@ fn run_task<'a>(
exposed_to_host,
abilities_store,
derived_symbols,
multimorphic_names,
)),
MakeSpecializations {
module_id,
@ -4962,7 +4924,6 @@ fn run_task<'a>(
module_timing,
world_abilities,
derived_symbols,
multimorphic_names,
} => Ok(make_specializations(
arena,
module_id,
@ -4975,7 +4936,6 @@ fn run_task<'a>(
target_info,
world_abilities,
derived_symbols,
multimorphic_names,
)),
}?;

View file

@ -998,10 +998,7 @@ define_builtins! {
// Fake module for storing derived function symbols
1 DERIVED: "#Derived" => {
}
// Fake module for storing fresh multimorphic function symbol names
2 MULTIMORPHIC: "#Multimorphic" => {
}
3 NUM: "Num" => {
2 NUM: "Num" => {
0 NUM_NUM: "Num" // the Num.Num type alias
1 NUM_I128: "I128" // the Num.I128 type alias
2 NUM_U128: "U128" // the Num.U128 type alias
@ -1144,7 +1141,7 @@ define_builtins! {
139 NUM_MAX_F64: "maxF64"
140 NUM_MIN_F64: "minF64"
}
4 BOOL: "Bool" => {
3 BOOL: "Bool" => {
0 BOOL_BOOL: "Bool" // the Bool.Bool type alias
1 BOOL_FALSE: "False" imported // Bool.Bool = [False, True]
// NB: not strictly needed; used for finding tag names in error suggestions
@ -1157,7 +1154,7 @@ define_builtins! {
7 BOOL_EQ: "isEq"
8 BOOL_NEQ: "isNotEq"
}
5 STR: "Str" => {
4 STR: "Str" => {
0 STR_STR: "Str" imported // the Str.Str type alias
1 STR_IS_EMPTY: "isEmpty"
2 STR_APPEND: "#append" // unused
@ -1194,7 +1191,7 @@ define_builtins! {
33 STR_TO_I8: "toI8"
34 STR_TO_SCALARS: "toScalars"
}
6 LIST: "List" => {
5 LIST: "List" => {
0 LIST_LIST: "List" imported // the List.List type alias
1 LIST_IS_EMPTY: "isEmpty"
2 LIST_GET: "get"
@ -1260,7 +1257,7 @@ define_builtins! {
62 LIST_WITH_CAPACITY: "withCapacity"
63 LIST_ITERATE: "iterate"
}
7 RESULT: "Result" => {
6 RESULT: "Result" => {
0 RESULT_RESULT: "Result" // the Result.Result type alias
1 RESULT_OK: "Ok" imported // Result.Result a e = [Ok a, Err e]
// NB: not strictly needed; used for finding tag names in error suggestions
@ -1273,7 +1270,7 @@ define_builtins! {
7 RESULT_IS_OK: "isOk"
8 RESULT_IS_ERR: "isErr"
}
8 DICT: "Dict" => {
7 DICT: "Dict" => {
0 DICT_DICT: "Dict" imported // the Dict.Dict type alias
1 DICT_EMPTY: "empty"
2 DICT_SINGLE: "single"
@ -1292,7 +1289,7 @@ define_builtins! {
13 DICT_INTERSECTION: "intersection"
14 DICT_DIFFERENCE: "difference"
}
9 SET: "Set" => {
8 SET: "Set" => {
0 SET_SET: "Set" imported // the Set.Set type alias
1 SET_EMPTY: "empty"
2 SET_SINGLE: "single"
@ -1309,12 +1306,12 @@ define_builtins! {
13 SET_CONTAINS: "contains"
14 SET_TO_DICT: "toDict"
}
10 BOX: "Box" => {
9 BOX: "Box" => {
0 BOX_BOX_TYPE: "Box" imported // the Box.Box opaque type
1 BOX_BOX_FUNCTION: "box" // Box.box
2 BOX_UNBOX: "unbox"
}
11 ENCODE: "Encode" => {
10 ENCODE: "Encode" => {
0 ENCODE_ENCODER: "Encoder"
1 ENCODE_ENCODING: "Encoding"
2 ENCODE_TO_ENCODER: "toEncoder"
@ -1342,9 +1339,9 @@ define_builtins! {
24 ENCODE_APPEND: "append"
25 ENCODE_TO_BYTES: "toBytes"
}
12 JSON: "Json" => {
11 JSON: "Json" => {
0 JSON_JSON: "Json"
}
num_modules: 13 // Keep this count up to date by hand! (TODO: see the mut_map! macro for how we could determine this count correctly in the macro)
num_modules: 12 // Keep this count up to date by hand! (TODO: see the mut_map! macro for how we could determine this count correctly in the macro)
}

View file

@ -2,7 +2,7 @@
use crate::layout::{
Builtin, ClosureRepresentation, LambdaName, LambdaSet, Layout, LayoutCache, LayoutProblem,
MultimorphicNames, RawFunctionLayout, TagIdIntType, TagOrClosure, UnionLayout, WrappedVariant,
RawFunctionLayout, TagIdIntType, TagOrClosure, UnionLayout, WrappedVariant,
};
use bumpalo::collections::{CollectIn, Vec};
use bumpalo::Bump;
@ -824,25 +824,19 @@ impl<'a> SymbolSpecializations<'a> {
let arena = env.arena;
let subs: &Subs = env.subs;
let layout =
match layout_cache.from_var(arena, specialization_var, subs, env.multimorphic_names) {
Ok(layout) => layout,
// This can happen when the def symbol has a type error. In such cases just use the
// def symbol, which is erroring.
Err(_) => return symbol,
};
let layout = match layout_cache.from_var(arena, specialization_var, subs) {
Ok(layout) => layout,
// This can happen when the def symbol has a type error. In such cases just use the
// def symbol, which is erroring.
Err(_) => return symbol,
};
let is_closure = matches!(
subs.get_content_without_compacting(specialization_var),
Content::Structure(FlatType::Func(..))
);
let function_mark = if is_closure {
let fn_layout = match layout_cache.raw_from_var(
arena,
specialization_var,
subs,
env.multimorphic_names,
) {
let fn_layout = match layout_cache.raw_from_var(arena, specialization_var, subs) {
Ok(layout) => layout,
// This can happen when the def symbol has a type error. In such cases just use the
// def symbol, which is erroring.
@ -1024,7 +1018,7 @@ impl<'a> Procs<'a> {
layout_cache: &mut LayoutCache<'a>,
) -> Result<ProcLayout<'a>, RuntimeError> {
let raw_layout = layout_cache
.raw_from_var(env.arena, annotation, env.subs, env.multimorphic_names)
.raw_from_var(env.arena, annotation, env.subs)
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
let top_level = ProcLayout::from_raw(env.arena, raw_layout, name.captures_niche);
@ -1303,7 +1297,6 @@ pub struct Env<'a, 'i> {
pub call_specialization_counter: u32,
pub abilities: AbilitiesView<'i>,
pub derived_symbols: &'i GlobalDerivedSymbols,
pub multimorphic_names: &'i mut MultimorphicNames,
}
impl<'a, 'i> Env<'a, 'i> {
@ -2902,7 +2895,7 @@ fn specialize_external<'a>(
for (symbol, variable) in host_exposed_variables {
let layout = layout_cache
.raw_from_var(env.arena, *variable, env.subs, env.multimorphic_names)
.raw_from_var(env.arena, *variable, env.subs)
.unwrap();
let name = env.unique_symbol();
@ -3229,7 +3222,7 @@ fn build_specialized_proc_from_var<'a>(
pattern_symbols: &[Symbol],
fn_var: Variable,
) -> Result<SpecializedLayout<'a>, LayoutProblem> {
match layout_cache.raw_from_var(env.arena, fn_var, env.subs, env.multimorphic_names)? {
match layout_cache.raw_from_var(env.arena, fn_var, env.subs)? {
RawFunctionLayout::Function(pattern_layouts, closure_layout, ret_layout) => {
let mut pattern_layouts_vec = Vec::with_capacity_in(pattern_layouts.len(), env.arena);
pattern_layouts_vec.extend_from_slice(pattern_layouts);
@ -3448,7 +3441,7 @@ where
// for debugging only
let raw = layout_cache
.raw_from_var(env.arena, fn_var, env.subs, env.multimorphic_names)
.raw_from_var(env.arena, fn_var, env.subs)
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
let raw = if procs.is_module_thunk(proc_name.name()) {
@ -3587,7 +3580,7 @@ fn specialize_naked_symbol<'a>(
return result;
} else if env.is_imported_symbol(symbol) {
match layout_cache.from_var(env.arena, variable, env.subs, env.multimorphic_names) {
match layout_cache.from_var(env.arena, variable, env.subs) {
Err(e) => panic!("invalid layout {:?}", e),
Ok(_) => {
// this is a 0-arity thunk
@ -3969,7 +3962,6 @@ pub fn with_hole<'a>(
record_var,
env.subs,
env.target_info,
env.multimorphic_names,
) {
Ok(fields) => fields,
Err(_) => return Stmt::RuntimeError("Can't create record with improper layout"),
@ -4023,7 +4015,7 @@ pub fn with_hole<'a>(
// creating a record from the var will unpack it if it's just a single field.
let layout = layout_cache
.from_var(env.arena, record_var, env.subs, env.multimorphic_names)
.from_var(env.arena, record_var, env.subs)
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
let field_symbols = field_symbols.into_bump_slice();
@ -4081,8 +4073,8 @@ pub fn with_hole<'a>(
final_else,
} => {
match (
layout_cache.from_var(env.arena, branch_var, env.subs, env.multimorphic_names),
layout_cache.from_var(env.arena, cond_var, env.subs, env.multimorphic_names),
layout_cache.from_var(env.arena, branch_var, env.subs),
layout_cache.from_var(env.arena, cond_var, env.subs),
) {
(Ok(ret_layout), Ok(cond_layout)) => {
// if the hole is a return, then we don't need to merge the two
@ -4181,7 +4173,7 @@ pub fn with_hole<'a>(
}
let layout = layout_cache
.from_var(env.arena, branch_var, env.subs, env.multimorphic_names)
.from_var(env.arena, branch_var, env.subs)
.unwrap_or_else(|err| {
panic!("TODO turn fn_var into a RuntimeError {:?}", err)
});
@ -4248,7 +4240,7 @@ pub fn with_hole<'a>(
);
let layout = layout_cache
.from_var(env.arena, expr_var, env.subs, env.multimorphic_names)
.from_var(env.arena, expr_var, env.subs)
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
let param = Param {
@ -4271,8 +4263,7 @@ pub fn with_hole<'a>(
..
} if loc_elems.is_empty() => {
// because an empty list has an unknown element type, it is handled differently
let opt_elem_layout =
layout_cache.from_var(env.arena, elem_var, env.subs, env.multimorphic_names);
let opt_elem_layout = layout_cache.from_var(env.arena, elem_var, env.subs);
match opt_elem_layout {
Ok(elem_layout) => {
@ -4326,7 +4317,7 @@ pub fn with_hole<'a>(
let arg_symbols = arg_symbols.into_bump_slice();
let elem_layout = layout_cache
.from_var(env.arena, elem_var, env.subs, env.multimorphic_names)
.from_var(env.arena, elem_var, env.subs)
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
let expr = Expr::Array {
@ -4362,7 +4353,6 @@ pub fn with_hole<'a>(
record_var,
env.subs,
env.target_info,
env.multimorphic_names,
) {
Ok(fields) => fields,
Err(_) => return Stmt::RuntimeError("Can't access record with improper layout"),
@ -4413,7 +4403,7 @@ pub fn with_hole<'a>(
};
let layout = layout_cache
.from_var(env.arena, field_var, env.subs, env.multimorphic_names)
.from_var(env.arena, field_var, env.subs)
.unwrap_or_else(|err| {
panic!("TODO turn fn_var into a RuntimeError {:?}", err)
});
@ -4460,12 +4450,7 @@ pub fn with_hole<'a>(
Ok(_) => {
let raw_layout = return_on_layout_error!(
env,
layout_cache.raw_from_var(
env.arena,
function_type,
env.subs,
env.multimorphic_names,
)
layout_cache.raw_from_var(env.arena, function_type, env.subs,)
);
match raw_layout {
@ -4513,7 +4498,6 @@ pub fn with_hole<'a>(
record_var,
env.subs,
env.target_info,
env.multimorphic_names,
) {
Ok(fields) => fields,
Err(_) => return Stmt::RuntimeError("Can't update record with improper layout"),
@ -4558,7 +4542,7 @@ pub fn with_hole<'a>(
let symbols = symbols.into_bump_slice();
let record_layout = layout_cache
.from_var(env.arena, record_var, env.subs, env.multimorphic_names)
.from_var(env.arena, record_var, env.subs)
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
let field_layouts = match &record_layout {
@ -4666,12 +4650,7 @@ pub fn with_hole<'a>(
}) => {
let loc_body = *boxed_body;
let raw = layout_cache.raw_from_var(
env.arena,
function_type,
env.subs,
env.multimorphic_names,
);
let raw = layout_cache.raw_from_var(env.arena, function_type, env.subs);
match return_on_layout_error!(env, raw) {
RawFunctionLayout::ZeroArgumentThunk(_) => {
@ -4805,12 +4784,7 @@ pub fn with_hole<'a>(
let full_layout = return_on_layout_error!(
env,
layout_cache.raw_from_var(
env.arena,
fn_var,
env.subs,
env.multimorphic_names,
)
layout_cache.raw_from_var(env.arena, fn_var, env.subs,)
);
// if the function expression (loc_expr) is already a symbol,
@ -4988,10 +4962,8 @@ pub fn with_hole<'a>(
let arg_symbols = arg_symbols.into_bump_slice();
// layout of the return type
let layout = return_on_layout_error!(
env,
layout_cache.from_var(env.arena, ret_var, env.subs, env.multimorphic_names,)
);
let layout =
return_on_layout_error!(env, layout_cache.from_var(env.arena, ret_var, env.subs,));
let call = self::Call {
call_type: CallType::Foreign {
@ -5026,10 +4998,8 @@ pub fn with_hole<'a>(
let arg_symbols = arg_symbols.into_bump_slice();
// layout of the return type
let layout = return_on_layout_error!(
env,
layout_cache.from_var(env.arena, ret_var, env.subs, env.multimorphic_names,)
);
let layout =
return_on_layout_error!(env, layout_cache.from_var(env.arena, ret_var, env.subs,));
macro_rules! match_on_closure_argument {
( $ho:ident, [$($x:ident),* $(,)?]) => {{
@ -5039,7 +5009,7 @@ pub fn with_hole<'a>(
let closure_data_layout = return_on_layout_error!(
env,
layout_cache.raw_from_var(env.arena, closure_data_var, env.subs,env.multimorphic_names)
layout_cache.raw_from_var(env.arena, closure_data_var, env.subs)
);
// NB: I don't think the top_level here can capture anything??
@ -5289,7 +5259,7 @@ where
.into_iter()
.map(|(_, var)| {
layout_cache
.from_var(env.arena, *var, env.subs, env.multimorphic_names)
.from_var(env.arena, *var, env.subs)
.expect("layout problem for capture")
})
.collect_in::<Vec<_>>(env.arena);
@ -5421,13 +5391,8 @@ fn convert_tag_union<'a>(
arena: &'a Bump,
) -> Stmt<'a> {
use crate::layout::UnionVariant::*;
let res_variant = crate::layout::union_sorted_tags(
env.arena,
variant_var,
env.subs,
env.target_info,
env.multimorphic_names,
);
let res_variant =
crate::layout::union_sorted_tags(env.arena, variant_var, env.subs, env.target_info);
let variant = match res_variant {
Ok(cached) => cached,
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
@ -5486,7 +5451,7 @@ fn convert_tag_union<'a>(
// Layout will unpack this unwrapped tack if it only has one (non-zero-sized) field
let layout = layout_cache
.from_var(env.arena, variant_var, env.subs, env.multimorphic_names)
.from_var(env.arena, variant_var, env.subs)
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
// even though this was originally a Tag, we treat it as a Struct from now on
@ -5514,7 +5479,7 @@ fn convert_tag_union<'a>(
// version is not the same as the minimal version.
let union_layout = match return_on_layout_error!(
env,
layout_cache.from_var(env.arena, variant_var, env.subs, env.multimorphic_names,)
layout_cache.from_var(env.arena, variant_var, env.subs,)
) {
Layout::Union(ul) => ul,
_ => unreachable!(),
@ -5712,7 +5677,7 @@ fn tag_union_to_function<'a>(
// only need to construct closure data
let raw_layout = return_on_layout_error!(
env,
layout_cache.raw_from_var(env.arena, whole_var, env.subs, env.multimorphic_names,)
layout_cache.raw_from_var(env.arena, whole_var, env.subs,)
);
match raw_layout {
@ -5753,7 +5718,7 @@ fn sorted_field_symbols<'a>(
for (var, mut arg) in args.drain(..) {
// Layout will unpack this unwrapped tag if it only has one (non-zero-sized) field
let layout = match layout_cache.from_var(env.arena, var, env.subs, env.multimorphic_names) {
let layout = match layout_cache.from_var(env.arena, var, env.subs) {
Ok(cached) => cached,
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
// this argument has type `forall a. a`, which is isomorphic to
@ -5851,13 +5816,7 @@ fn register_capturing_closure<'a>(
let captured_symbols = match *env.subs.get_content_without_compacting(function_type) {
Content::Structure(FlatType::Func(_, closure_var, _)) => {
match LambdaSet::from_var(
env.arena,
env.subs,
closure_var,
env.target_info,
env.multimorphic_names,
) {
match LambdaSet::from_var(env.arena, env.subs, closure_var, env.target_info) {
Ok(lambda_set) => {
if let Layout::Struct {
field_layouts: &[], ..
@ -5888,12 +5847,7 @@ fn register_capturing_closure<'a>(
captured_symbols.is_empty(),
"{:?} with layout {:?} {:?} {:?}",
&captured_symbols,
layout_cache.raw_from_var(
env.arena,
function_type,
env.subs,
env.multimorphic_names,
),
layout_cache.raw_from_var(env.arena, function_type, env.subs,),
env.subs,
(function_type, closure_type),
);
@ -5972,10 +5926,10 @@ pub fn from_can<'a>(
final_else,
} => {
let ret_layout = layout_cache
.from_var(env.arena, branch_var, env.subs, env.multimorphic_names)
.from_var(env.arena, branch_var, env.subs)
.expect("invalid ret_layout");
let cond_layout = layout_cache
.from_var(env.arena, cond_var, env.subs, env.multimorphic_names)
.from_var(env.arena, cond_var, env.subs)
.expect("invalid cond_layout");
let mut stmt = from_can(env, branch_var, final_else.value, procs, layout_cache);
@ -6019,8 +5973,7 @@ pub fn from_can<'a>(
let mut layouts = Vec::with_capacity_in(lookups_in_cond.len(), env.arena);
for (_, var) in lookups_in_cond {
let res_layout =
layout_cache.from_var(env.arena, var, env.subs, env.multimorphic_names);
let res_layout = layout_cache.from_var(env.arena, var, env.subs);
let layout = return_on_layout_error!(env, res_layout);
layouts.push(layout);
}
@ -6187,15 +6140,11 @@ fn from_can_when<'a>(
}
let opt_branches = to_opt_branches(env, procs, branches, exhaustive_mark, layout_cache);
let cond_layout = return_on_layout_error!(
env,
layout_cache.from_var(env.arena, cond_var, env.subs, env.multimorphic_names,)
);
let cond_layout =
return_on_layout_error!(env, layout_cache.from_var(env.arena, cond_var, env.subs,));
let ret_layout = return_on_layout_error!(
env,
layout_cache.from_var(env.arena, expr_var, env.subs, env.multimorphic_names,)
);
let ret_layout =
return_on_layout_error!(env, layout_cache.from_var(env.arena, expr_var, env.subs,));
let arena = env.arena;
let it = opt_branches
@ -7188,8 +7137,7 @@ where
for (_, (variable, left)) in needed_specializations_of_left {
add_needed_external(procs, env, variable, LambdaName::thunk(right));
let res_layout =
layout_cache.from_var(env.arena, variable, env.subs, env.multimorphic_names);
let res_layout = layout_cache.from_var(env.arena, variable, env.subs);
let layout = return_on_layout_error!(env, res_layout);
result = force_thunk(env, right, layout, left, env.arena.alloc(result));
@ -7279,12 +7227,7 @@ fn specialize_symbol<'a>(
None => {
match arg_var {
Some(arg_var) if env.is_imported_symbol(original) => {
let raw = match layout_cache.raw_from_var(
env.arena,
arg_var,
env.subs,
env.multimorphic_names,
) {
let raw = match layout_cache.raw_from_var(env.arena, arg_var, env.subs) {
Ok(v) => v,
Err(e) => return_on_layout_error_help!(env, e),
};
@ -7347,7 +7290,7 @@ fn specialize_symbol<'a>(
// to it in the IR.
let res_layout = return_on_layout_error!(
env,
layout_cache.raw_from_var(env.arena, arg_var, env.subs, env.multimorphic_names,)
layout_cache.raw_from_var(env.arena, arg_var, env.subs,)
);
// we have three kinds of functions really. Plain functions, closures by capture,
@ -7587,7 +7530,7 @@ fn call_by_name<'a>(
hole: &'a Stmt<'a>,
) -> Stmt<'a> {
// Register a pending_specialization for this function
match layout_cache.raw_from_var(env.arena, fn_var, env.subs, env.multimorphic_names) {
match layout_cache.raw_from_var(env.arena, fn_var, env.subs) {
Err(LayoutProblem::UnresolvedTypeVar(var)) => {
let msg = format!(
"Hit an unresolved type variable {:?} when creating a layout for {:?} (var {:?})",
@ -7775,7 +7718,7 @@ fn call_by_name_help<'a>(
// the variables of the given arguments
let mut pattern_vars = Vec::with_capacity_in(loc_args.len(), arena);
for (var, _) in &loc_args {
match layout_cache.from_var(env.arena, *var, env.subs, env.multimorphic_names) {
match layout_cache.from_var(env.arena, *var, env.subs) {
Ok(_) => {
pattern_vars.push(*var);
}
@ -8436,14 +8379,9 @@ fn from_can_pattern_help<'a>(
use crate::layout::UnionVariant::*;
use roc_exhaustive::Union;
let res_variant = crate::layout::union_sorted_tags(
env.arena,
*whole_var,
env.subs,
env.target_info,
env.multimorphic_names,
)
.map_err(Into::into);
let res_variant =
crate::layout::union_sorted_tags(env.arena, *whole_var, env.subs, env.target_info)
.map_err(Into::into);
let variant = match res_variant {
Ok(cached) => cached,
@ -8526,12 +8464,12 @@ fn from_can_pattern_help<'a>(
arguments.sort_by(|arg1, arg2| {
let size1 = layout_cache
.from_var(env.arena, arg1.0, env.subs, env.multimorphic_names)
.from_var(env.arena, arg1.0, env.subs)
.map(|x| x.alignment_bytes(env.target_info))
.unwrap_or(0);
let size2 = layout_cache
.from_var(env.arena, arg2.0, env.subs, env.multimorphic_names)
.from_var(env.arena, arg2.0, env.subs)
.map(|x| x.alignment_bytes(env.target_info))
.unwrap_or(0);
@ -8566,12 +8504,10 @@ fn from_can_pattern_help<'a>(
let mut temp = arguments.clone();
temp.sort_by(|arg1, arg2| {
let layout1 = layout_cache
.from_var(env.arena, arg1.0, env.subs, env.multimorphic_names)
.unwrap();
let layout2 = layout_cache
.from_var(env.arena, arg2.0, env.subs, env.multimorphic_names)
.unwrap();
let layout1 =
layout_cache.from_var(env.arena, arg1.0, env.subs).unwrap();
let layout2 =
layout_cache.from_var(env.arena, arg2.0, env.subs).unwrap();
let size1 = layout1.alignment_bytes(env.target_info);
let size2 = layout2.alignment_bytes(env.target_info);
@ -8586,12 +8522,7 @@ fn from_can_pattern_help<'a>(
// from `layouts` would unroll recursive tag unions, and that leads to
// problems down the line because we hash layouts and an unrolled
// version is not the same as the minimal version.
let layout = match layout_cache.from_var(
env.arena,
*whole_var,
env.subs,
env.multimorphic_names,
) {
let layout = match layout_cache.from_var(env.arena, *whole_var, env.subs) {
Ok(Layout::Union(ul)) => ul,
_ => unreachable!(),
};
@ -8882,7 +8813,7 @@ fn from_can_pattern_help<'a>(
} => {
let (arg_var, loc_arg_pattern) = &(**argument);
let arg_layout = layout_cache
.from_var(env.arena, *arg_var, env.subs, env.multimorphic_names)
.from_var(env.arena, *arg_var, env.subs)
.unwrap();
let mono_arg_pattern = from_can_pattern_help(
env,
@ -8903,14 +8834,9 @@ fn from_can_pattern_help<'a>(
..
} => {
// sorted fields based on the type
let sorted_fields = crate::layout::sort_record_fields(
env.arena,
*whole_var,
env.subs,
env.target_info,
env.multimorphic_names,
)
.map_err(RuntimeError::from)?;
let sorted_fields =
crate::layout::sort_record_fields(env.arena, *whole_var, env.subs, env.target_info)
.map_err(RuntimeError::from)?;
// sorted fields based on the destruct
let mut mono_destructs = Vec::with_capacity_in(destructs.len(), env.arena);

View file

@ -1,12 +1,11 @@
use crate::ir::Parens;
use bumpalo::collections::{CollectIn, Vec};
use bumpalo::collections::Vec;
use bumpalo::Bump;
use roc_builtins::bitcode::{FloatWidth, IntWidth};
use roc_collections::all::{default_hasher, MutMap};
use roc_collections::VecMap;
use roc_error_macros::{internal_error, todo_abilities};
use roc_module::ident::{Lowercase, TagName};
use roc_module::symbol::{IdentIds, Interns, ModuleId, Symbol};
use roc_module::symbol::{Interns, Symbol};
use roc_problem::can::RuntimeError;
use roc_target::{PtrWidth, TargetInfo};
use roc_types::subs::{
@ -17,7 +16,6 @@ use std::cmp::Ordering;
use std::collections::hash_map::{DefaultHasher, Entry};
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::sync::{Arc, Mutex};
use ven_pretty::{DocAllocator, DocBuilder};
// if your changes cause this number to go down, great!
@ -185,13 +183,8 @@ impl<'a> RawFunctionLayout<'a> {
let fn_args = fn_args.into_bump_slice();
let ret = arena.alloc(ret);
let lambda_set = LambdaSet::from_var(
env.arena,
env.subs,
closure_var,
env.target_info,
env.multimorphic_names,
)?;
let lambda_set =
LambdaSet::from_var(env.arena, env.subs, closure_var, env.target_info)?;
Ok(Self::Function(fn_args, lambda_set, ret))
}
@ -699,170 +692,6 @@ impl std::fmt::Debug for LambdaSet<'_> {
}
}
#[derive(Default, Debug)]
struct MultimorphicNamesTable {
/// (source symbol, captures layouts) -> multimorphic alias
///
/// SAFETY: actually, the `Layout` is alive only as long as the `arena` is alive. We take care
/// to promote new layouts to the owned arena. Since we are using a bump-allocating arena, the
/// references will never be invalidated until the arena is dropped, which happens when this
/// struct is dropped.
/// Also, the `Layout`s we owned are never exposed back via the public API.
inner: VecMap<(Symbol, &'static [Layout<'static>]), Symbol>,
arena: Bump,
ident_ids: IdentIds,
}
impl MultimorphicNamesTable {
fn get<'b>(&self, name: Symbol, captures_layouts: &'b [Layout<'b>]) -> Option<Symbol> {
self.inner.get(&(name, captures_layouts)).copied()
}
fn insert<'b>(&mut self, name: Symbol, captures_layouts: &'b [Layout<'b>]) -> Symbol {
debug_assert!(!self.inner.contains_key(&(name, captures_layouts)));
let new_ident = self.ident_ids.gen_unique();
let new_symbol = Symbol::new(ModuleId::MULTIMORPHIC, new_ident);
let captures_layouts = self.promote_layout_slice(captures_layouts);
self.inner.insert((name, captures_layouts), new_symbol);
new_symbol
}
fn alloc_st<T>(&self, v: T) -> &'static T {
unsafe { std::mem::transmute::<_, &'static Bump>(&self.arena) }.alloc(v)
}
fn promote_layout<'b>(&self, layout: Layout<'b>) -> Layout<'static> {
match layout {
Layout::Builtin(builtin) => Layout::Builtin(self.promote_builtin(builtin)),
Layout::Struct {
field_order_hash,
field_layouts,
} => Layout::Struct {
field_order_hash,
field_layouts: self.promote_layout_slice(field_layouts),
},
Layout::Boxed(layout) => Layout::Boxed(self.alloc_st(self.promote_layout(*layout))),
Layout::Union(union_layout) => Layout::Union(self.promote_union_layout(union_layout)),
Layout::LambdaSet(lambda_set) => Layout::LambdaSet(self.promote_lambda_set(lambda_set)),
Layout::RecursivePointer => Layout::RecursivePointer,
}
}
fn promote_layout_slice<'b>(&self, layouts: &'b [Layout<'b>]) -> &'static [Layout<'static>] {
layouts
.iter()
.map(|layout| self.promote_layout(*layout))
.collect_in::<Vec<_>>(unsafe { std::mem::transmute(&self.arena) })
.into_bump_slice()
}
fn promote_layout_slice_slices<'b>(
&self,
layout_slices: &'b [&'b [Layout<'b>]],
) -> &'static [&'static [Layout<'static>]] {
layout_slices
.iter()
.map(|slice| self.promote_layout_slice(slice))
.collect_in::<Vec<_>>(unsafe { std::mem::transmute(&self.arena) })
.into_bump_slice()
}
fn promote_builtin(&self, builtin: Builtin) -> Builtin<'static> {
match builtin {
Builtin::Int(w) => Builtin::Int(w),
Builtin::Float(w) => Builtin::Float(w),
Builtin::Bool => Builtin::Bool,
Builtin::Decimal => Builtin::Decimal,
Builtin::Str => Builtin::Str,
Builtin::Dict(k, v) => Builtin::Dict(
self.alloc_st(self.promote_layout(*k)),
self.alloc_st(self.promote_layout(*v)),
),
Builtin::Set(k) => Builtin::Set(self.alloc_st(self.promote_layout(*k))),
Builtin::List(l) => Builtin::Set(self.alloc_st(self.promote_layout(*l))),
}
}
fn promote_union_layout(&self, union_layout: UnionLayout) -> UnionLayout<'static> {
match union_layout {
UnionLayout::NonRecursive(slices) => {
UnionLayout::NonRecursive(self.promote_layout_slice_slices(slices))
}
UnionLayout::Recursive(slices) => {
UnionLayout::Recursive(self.promote_layout_slice_slices(slices))
}
UnionLayout::NonNullableUnwrapped(slice) => {
UnionLayout::NonNullableUnwrapped(self.promote_layout_slice(slice))
}
UnionLayout::NullableWrapped {
nullable_id,
other_tags,
} => UnionLayout::NullableWrapped {
nullable_id,
other_tags: self.promote_layout_slice_slices(other_tags),
},
UnionLayout::NullableUnwrapped {
nullable_id,
other_fields,
} => UnionLayout::NullableUnwrapped {
nullable_id,
other_fields: self.promote_layout_slice(other_fields),
},
}
}
fn promote_lambda_set(&self, lambda_set: LambdaSet) -> LambdaSet<'static> {
let LambdaSet {
set,
representation,
} = lambda_set;
let set = set
.iter()
.map(|(name, slice)| (*name, self.promote_layout_slice(slice)))
.collect_in::<Vec<_>>(unsafe { std::mem::transmute(&self.arena) })
.into_bump_slice();
LambdaSet {
set,
representation: self.alloc_st(self.promote_layout(*representation)),
}
}
}
#[derive(Default, Debug)]
pub struct MultimorphicNames(Arc<Mutex<MultimorphicNamesTable>>);
impl Clone for MultimorphicNames {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
}
impl MultimorphicNames {
fn get_or_insert<'b>(&self, name: Symbol, captures_layouts: &'b [Layout<'b>]) -> Symbol {
let mut table = self.0.lock().unwrap();
match table.get(name, captures_layouts) {
Some(symbol) => symbol,
None => table.insert(name, captures_layouts),
}
}
/// Assumes there is only one clone still alive.
/// If there is more than one clone alive, `self` is returned.
pub fn try_unwrap_names(self) -> Result<IdentIds, Self> {
let mutex = Arc::try_unwrap(self.0).map_err(Self)?;
let table = mutex
.into_inner()
.expect("how can there be another lock if we consumed the only ref?");
Ok(table.ident_ids)
}
}
static_assertions::assert_eq_size!(&[Layout], Option<&[Layout]>);
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct LambdaName<'a> {
name: Symbol,
@ -1100,7 +929,6 @@ impl<'a> LambdaSet<'a> {
subs: &Subs,
closure_var: Variable,
target_info: TargetInfo,
multimorphic_names: &mut MultimorphicNames,
) -> Result<Self, LayoutProblem> {
match resolve_lambda_set(subs, closure_var) {
ResolvedLambdaSet::Set(mut lambdas) => {
@ -1123,7 +951,6 @@ impl<'a> LambdaSet<'a> {
subs,
seen: Vec::new_in(arena),
target_info,
multimorphic_names,
};
for var in variables {
@ -1177,7 +1004,6 @@ impl<'a> LambdaSet<'a> {
subs,
set_with_variables,
target_info,
multimorphic_names,
));
Ok(LambdaSet {
@ -1201,11 +1027,9 @@ impl<'a> LambdaSet<'a> {
subs: &Subs,
tags: std::vec::Vec<(Symbol, std::vec::Vec<Variable>)>,
target_info: TargetInfo,
multimorphic_names: &mut MultimorphicNames,
) -> Layout<'a> {
// otherwise, this is a closure with a payload
let variant =
union_sorted_tags_help(arena, tags, None, subs, target_info, multimorphic_names);
let variant = union_sorted_tags_help(arena, tags, None, subs, target_info);
use UnionVariant::*;
match variant {
@ -1311,7 +1135,6 @@ pub struct Env<'a, 'b> {
arena: &'a Bump,
seen: Vec<'a, Variable>,
subs: &'b Subs,
multimorphic_names: &'b mut MultimorphicNames,
}
impl<'a, 'b> Env<'a, 'b> {
@ -1752,7 +1575,6 @@ impl<'a> LayoutCache<'a> {
arena: &'a Bump,
var: Variable,
subs: &Subs,
multimorphic_names: &mut MultimorphicNames,
) -> Result<Layout<'a>, LayoutProblem> {
// Store things according to the root Variable, to avoid duplicate work.
let var = subs.get_root_key_without_compacting(var);
@ -1762,7 +1584,6 @@ impl<'a> LayoutCache<'a> {
subs,
seen: Vec::new_in(arena),
target_info: self.target_info,
multimorphic_names,
};
Layout::from_var(&mut env, var)
@ -1773,7 +1594,6 @@ impl<'a> LayoutCache<'a> {
arena: &'a Bump,
var: Variable,
subs: &Subs,
multimorphic_names: &mut MultimorphicNames,
) -> Result<RawFunctionLayout<'a>, LayoutProblem> {
// Store things according to the root Variable, to avoid duplicate work.
let var = subs.get_root_key_without_compacting(var);
@ -1783,7 +1603,6 @@ impl<'a> LayoutCache<'a> {
subs,
seen: Vec::new_in(arena),
target_info: self.target_info,
multimorphic_names,
};
RawFunctionLayout::from_var(&mut env, var)
}
@ -2177,13 +1996,8 @@ fn layout_from_flat_type<'a>(
}
}
Func(_, closure_var, _) => {
let lambda_set = LambdaSet::from_var(
env.arena,
env.subs,
closure_var,
env.target_info,
env.multimorphic_names,
)?;
let lambda_set =
LambdaSet::from_var(env.arena, env.subs, closure_var, env.target_info)?;
Ok(Layout::LambdaSet(lambda_set))
}
@ -2267,14 +2081,12 @@ pub fn sort_record_fields<'a>(
var: Variable,
subs: &Subs,
target_info: TargetInfo,
multimorphic_names: &mut MultimorphicNames,
) -> Result<Vec<'a, SortedField<'a>>, LayoutProblem> {
let mut env = Env {
arena,
subs,
seen: Vec::new_in(arena),
target_info,
multimorphic_names,
};
let (it, _) = match gather_fields_unsorted_iter(subs, RecordFields::empty(), var) {
@ -2481,7 +2293,6 @@ pub fn union_sorted_tags<'a>(
var: Variable,
subs: &Subs,
target_info: TargetInfo,
multimorphic_names: &mut MultimorphicNames,
) -> Result<UnionVariant<'a>, LayoutProblem> {
let var =
if let Content::RecursionVar { structure, .. } = subs.get_content_without_compacting(var) {
@ -2502,7 +2313,7 @@ pub fn union_sorted_tags<'a>(
| Err((_, Content::FlexVar(_) | Content::RigidVar(_)))
| Err((_, Content::RecursionVar { .. })) => {
let opt_rec_var = get_recursion_var(subs, var);
union_sorted_tags_help(arena, tags_vec, opt_rec_var, subs, target_info, multimorphic_names)
union_sorted_tags_help(arena, tags_vec, opt_rec_var, subs, target_info)
}
Err((_, Content::Error)) => return Err(LayoutProblem::Erroneous),
Err(other) => panic!("invalid content in tag union variable: {:?}", other),
@ -2728,7 +2539,6 @@ pub fn union_sorted_tags_help<'a, L>(
opt_rec_var: Option<Variable>,
subs: &Subs,
target_info: TargetInfo,
multimorphic_names: &mut MultimorphicNames,
) -> UnionVariant<'a>
where
L: Into<TagOrClosure> + Ord + Clone,
@ -2741,7 +2551,6 @@ where
subs,
seen: Vec::new_in(arena),
target_info,
multimorphic_names,
};
match tags_vec.len() {

View file

@ -123,6 +123,7 @@ fn build_app_mono<'a>(
let proc_layout = ProcLayout {
arguments: &[],
result: int_layout,
captures_niche: &[],
};
let mut app = MutMap::default();