Convert over Subs to use the new soa crate

This commit is contained in:
Richard Feldman 2024-10-10 00:17:59 -04:00
parent 586959780b
commit 2567c8b545
No known key found for this signature in database
GPG key ID: 5DE4EE30BB738EDF
17 changed files with 240 additions and 401 deletions

View file

@ -12,7 +12,7 @@ use roc_module::{
use roc_types::{
subs::{
self, AliasVariables, Descriptor, GetSubsSlice, OptVariable, RecordFields, Subs, SubsIndex,
SubsSlice, TupleElems, UnionLambdas, UnionTags, Variable, VariableSlice,
SubsSlice, TupleElems, UnionLambdas, UnionTags, Variable,
},
types::{RecordField, Uls},
};
@ -162,7 +162,7 @@ impl<'a> CopyEnv for AcrossSubs<'a> {
fn clone_field_names(&mut self, field_names: SubsSlice<Lowercase>) -> SubsSlice<Lowercase> {
SubsSlice::extend_new(
&mut self.target.field_names,
self.source.get_slice(field_names).iter().cloned(),
self.source.get_subs_slice(field_names).iter().cloned(),
)
}
@ -173,7 +173,10 @@ impl<'a> CopyEnv for AcrossSubs<'a> {
) -> SubsSlice<usize> {
SubsSlice::extend_new(
&mut self.target.tuple_elem_indices,
self.source.get_slice(tuple_elem_indices).iter().cloned(),
self.source
.get_subs_slice(tuple_elem_indices)
.iter()
.cloned(),
)
}
@ -181,7 +184,7 @@ impl<'a> CopyEnv for AcrossSubs<'a> {
fn clone_tag_names(&mut self, tag_names: SubsSlice<TagName>) -> SubsSlice<TagName> {
SubsSlice::extend_new(
&mut self.target.tag_names,
self.source.get_slice(tag_names).iter().cloned(),
self.source.get_subs_slice(tag_names).iter().cloned(),
)
}
@ -189,7 +192,7 @@ impl<'a> CopyEnv for AcrossSubs<'a> {
fn clone_lambda_names(&mut self, lambda_names: SubsSlice<Symbol>) -> SubsSlice<Symbol> {
SubsSlice::extend_new(
&mut self.target.symbol_names,
self.source.get_slice(lambda_names).iter().cloned(),
self.source.get_subs_slice(lambda_names).iter().cloned(),
)
}
@ -200,7 +203,7 @@ impl<'a> CopyEnv for AcrossSubs<'a> {
) -> SubsSlice<RecordField<()>> {
SubsSlice::extend_new(
&mut self.target.record_fields,
self.source.get_slice(record_fields).iter().copied(),
self.source.get_subs_slice(record_fields).iter().copied(),
)
}
}
@ -916,8 +919,7 @@ fn deep_copy_type_vars<C: CopyEnv>(
macro_rules! clone_var_slice {
($slice:expr) => {{
let new_arguments =
VariableSubsSlice::reserve_into_subs(env.target(), $slice.len());
let new_arguments = env.target().reserve_into_vars($slice.len());
for (target_index, var_index) in (new_arguments.indices()).zip($slice) {
let var = env.source()[var_index];
let copy_var = env.get_copy(var).into_variable().unwrap_or(var);
@ -1029,8 +1031,7 @@ fn deep_copy_type_vars<C: CopyEnv>(
}
perform_clone!({
let new_variable_slices =
SubsSlice::reserve_variable_slices(env.target(), tags.len());
let new_variable_slices = env.target().reserve_variable_slices(tags.len());
let it = (new_variable_slices.indices()).zip(tags.variables());
for (target_index, index) in it {
let slice = env.source()[index];
@ -1055,8 +1056,7 @@ fn deep_copy_type_vars<C: CopyEnv>(
}
perform_clone!({
let new_variable_slices =
SubsSlice::reserve_variable_slices(env.target(), tags.len());
let new_variable_slices = env.target().reserve_variable_slices(tags.len());
let it = (new_variable_slices.indices()).zip(tags.variables());
for (target_index, index) in it {
let slice = env.source()[index];
@ -1132,8 +1132,7 @@ fn deep_copy_type_vars<C: CopyEnv>(
let new_ambient_function = descend_var!(ambient_function);
perform_clone!({
let new_variable_slices =
SubsSlice::reserve_variable_slices(env.target(), solved.len());
let new_variable_slices = env.target().reserve_variable_slices(solved.len());
let it = (new_variable_slices.indices()).zip(solved.variables());
for (target_index, index) in it {
let slice = env.source()[index];
@ -1147,8 +1146,7 @@ fn deep_copy_type_vars<C: CopyEnv>(
let new_solved =
UnionLambdas::from_slices(new_solved_labels, new_variable_slices);
let new_unspecialized =
SubsSlice::reserve_uls_slice(env.target(), unspecialized.len());
let new_unspecialized = env.target().reserve_uls_slice(unspecialized.len());
for (target_index, uls_index) in
(new_unspecialized.into_iter()).zip(unspecialized.into_iter())
{

View file

@ -68,7 +68,8 @@ fn wrap_in_decode_custom_decode_with(
// Decode.decodeWith : bytes, inner_decoder, fmt -> DecoderResult (List val)
let this_decode_with_var_slice =
SubsSlice::insert_into_subs(env.subs, [bytes_var, inner_decoder_var, fmt_var]);
env.subs
.insert_into_vars([bytes_var, inner_decoder_var, fmt_var]);
let this_decode_with_clos_var = env.subs.fresh_unnamed_flex_var();
let this_decode_with_ret_var = env.subs.fresh_unnamed_flex_var();
let this_decode_with_fn_var = synth_var(
@ -131,7 +132,7 @@ fn wrap_in_decode_custom_decode_with(
);
// bytes, fmt -[[fn_name]]-> DecoderResult (List elem)
let args_slice = SubsSlice::insert_into_subs(env.subs, [bytes_var, fmt_var]);
let args_slice = env.subs.insert_into_vars([bytes_var, fmt_var]);
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(
@ -173,7 +174,7 @@ fn wrap_in_decode_custom_decode_with(
let decode_custom_type = env.import_builtin_symbol_var(Symbol::DECODE_CUSTOM);
// (List U8, fmt -> DecodeResult (List elem)) -> Decoder (List elem) fmt
let this_decode_custom_args = SubsSlice::insert_into_subs(env.subs, [custom_var]);
let this_decode_custom_args = env.subs.insert_into_vars([custom_var]);
let this_decode_custom_clos_var = env.subs.fresh_unnamed_flex_var();
let this_decode_custom_ret_var = env.subs.fresh_unnamed_flex_var();
let this_decode_custom_fn_var = synth_var(

View file

@ -5,7 +5,7 @@ use roc_module::called_via::CalledVia;
use roc_module::symbol::Symbol;
use roc_region::all::Loc;
use roc_types::subs::{Content, FlatType, GetSubsSlice, SubsSlice, Variable};
use roc_types::subs::{Content, FlatType, GetSubsSlice, Variable};
use roc_types::types::AliasKind;
use crate::decoding::wrap_in_decode_custom_decode_with;
@ -56,7 +56,7 @@ pub(crate) fn decoder(env: &mut Env<'_>, _def_symbol: Symbol) -> (Expr, Variable
let decode_list_fn_var = env.import_builtin_symbol_var(Symbol::DECODE_LIST);
// Decoder elem fmt -a-> b
let elem_decoder_var_slice = SubsSlice::insert_into_subs(env.subs, [elem_decoder_var]);
let elem_decoder_var_slice = env.subs.insert_into_vars([elem_decoder_var]);
let this_decode_list_clos_var = env.subs.fresh_unnamed_flex_var();
let this_decode_list_ret_var = env.subs.fresh_unnamed_flex_var();
let this_decode_list_fn_var = synth_var(

View file

@ -9,8 +9,8 @@ use roc_module::ident::Lowercase;
use roc_module::symbol::Symbol;
use roc_region::all::{Loc, Region};
use roc_types::subs::{
Content, ExhaustiveMark, FlatType, LambdaSet, OptVariable, RecordFields, RedundantMark,
SubsSlice, TagExt, UnionLambdas, UnionTags, Variable,
Content, ExhaustiveMark, FlatType, LambdaSet, OptVariable, RecordFields, RedundantMark, TagExt,
UnionLambdas, UnionTags, Variable,
};
use roc_types::types::RecordField;
@ -66,7 +66,7 @@ use super::wrap_in_decode_custom_decode_with;
/// Ok f1 -> Ok { f1, f0 }
/// Err _ -> Err TooShort
/// Err _ -> Err TooShort
///
///
/// Decode.custom \bytes, fmt -> Decode.decodeWith bytes (Decode.record initialState stepField finalizer) fmt
///```
pub(crate) fn decoder(
@ -108,7 +108,8 @@ pub(crate) fn decoder(
let decode_record_var = env.import_builtin_symbol_var(Symbol::DECODE_RECORD);
let this_decode_record_var = {
let flat_type = FlatType::Func(
SubsSlice::insert_into_subs(env.subs, [initial_state_var, step_var, finalizer_var]),
env.subs
.insert_into_vars([initial_state_var, step_var, finalizer_var]),
decode_record_lambda_set,
record_decoder_var,
);
@ -200,7 +201,7 @@ pub(super) fn step_field(
let mut branches = Vec::with_capacity(fields.len() + 1);
let keep_payload_var = env.subs.fresh_unnamed_flex_var();
let keep_or_skip_var = {
let keep_payload_subs_slice = SubsSlice::insert_into_subs(env.subs, [keep_payload_var]);
let keep_payload_subs_slice = env.subs.insert_into_vars([keep_payload_var]);
let flat_type = FlatType::TagUnion(
UnionTags::insert_slices_into_subs(
env.subs,
@ -337,7 +338,7 @@ pub(super) fn step_field(
};
{
let args_slice = SubsSlice::insert_into_subs(env.subs, [state_record_var, Variable::STR]);
let args_slice = env.subs.insert_into_vars([state_record_var, Variable::STR]);
env.subs.set_content(
function_type,
@ -403,7 +404,7 @@ fn custom_decoder(env: &mut Env<'_>, args: DecodingFieldArgs) -> (Variable, Expr
let decode_custom_var = env.import_builtin_symbol_var(Symbol::DECODE_CUSTOM);
let decode_custom_closure_var = env.subs.fresh_unnamed_flex_var();
let this_decode_custom_var = {
let subs_slice = SubsSlice::insert_into_subs(env.subs, [this_custom_callback_var]);
let subs_slice = env.subs.insert_into_vars([this_custom_callback_var]);
let flat_type =
FlatType::Func(subs_slice, decode_custom_closure_var, decode_custom_ret_var);
@ -566,7 +567,7 @@ fn custom_decoder_lambda(env: &mut Env<'_>, args: DecodingFieldArgs) -> (Variabl
ambient_function: this_custom_callback_var,
});
let custom_callback_lambda_set_var = synth_var(env.subs, content);
let subs_slice = SubsSlice::insert_into_subs(env.subs, [bytes_arg_var, fmt_arg_var]);
let subs_slice = env.subs.insert_into_vars([bytes_arg_var, fmt_arg_var]);
env.subs.set_content(
this_custom_callback_var,
@ -979,7 +980,7 @@ pub(super) fn finalizer(
};
let closure_type = synth_var(env.subs, Content::LambdaSet(lambda_set));
let flat_type = FlatType::Func(
SubsSlice::insert_into_subs(env.subs, [state_record_var, fmt_arg_var]),
env.subs.insert_into_vars([state_record_var, fmt_arg_var]),
closure_type,
return_type_var,
);
@ -1020,7 +1021,7 @@ pub(super) fn finalizer(
/// decRec-> decRec.result
/// Ok a -> Ok a
/// ```
/// Tries to decode the field with a zero byte input if it missing,
/// Tries to decode the field with a zero byte input if it missing,
/// this allows the decoder to decode types that have a state for "missing", such as
/// an "Option" type.
///
@ -1266,8 +1267,9 @@ fn make_decode_with_vars(
let decode_with_var = env.import_builtin_symbol_var(Symbol::DECODE_DECODE_WITH);
let lambda_set_var = env.subs.fresh_unnamed_flex_var();
let this_decode_with_var = {
let subs_slice =
SubsSlice::insert_into_subs(env.subs, [bytes_arg_var, decoder_var, fmt_arg_var]);
let subs_slice = env
.subs
.insert_into_vars([bytes_arg_var, decoder_var, fmt_arg_var]);
let this_decode_with_var = synth_var(
env.subs,
Content::Structure(FlatType::Func(subs_slice, lambda_set_var, rec_var)),

View file

@ -9,8 +9,8 @@ use roc_module::ident::Lowercase;
use roc_module::symbol::Symbol;
use roc_region::all::{Loc, Region};
use roc_types::subs::{
Content, ExhaustiveMark, FlatType, LambdaSet, OptVariable, RecordFields, RedundantMark,
SubsSlice, TagExt, TupleElems, UnionLambdas, UnionTags, Variable,
Content, ExhaustiveMark, FlatType, LambdaSet, OptVariable, RecordFields, RedundantMark, TagExt,
TupleElems, UnionLambdas, UnionTags, Variable,
};
use roc_types::types::RecordField;
@ -98,7 +98,8 @@ pub(crate) fn decoder(env: &mut Env, _def_symbol: Symbol, arity: u32) -> (Expr,
let decode_record_var = env.import_builtin_symbol_var(Symbol::DECODE_TUPLE);
let this_decode_record_var = {
let flat_type = FlatType::Func(
SubsSlice::insert_into_subs(env.subs, [state_var, step_var, finalizer_var]),
env.subs
.insert_into_vars([state_var, step_var, finalizer_var]),
decode_record_lambda_set,
tuple_decoder_var,
);
@ -190,7 +191,7 @@ fn step_elem(
let mut branches = Vec::with_capacity(index_vars.len() + 1);
let keep_payload_var = env.subs.fresh_unnamed_flex_var();
let keep_or_skip_var = {
let keep_payload_subs_slice = SubsSlice::insert_into_subs(env.subs, [keep_payload_var]);
let keep_payload_subs_slice = env.subs.insert_into_vars([keep_payload_var]);
let flat_type = FlatType::TagUnion(
UnionTags::insert_slices_into_subs(
env.subs,
@ -270,10 +271,9 @@ fn step_elem(
let decode_with_var = env.import_builtin_symbol_var(Symbol::DECODE_DECODE_WITH);
let lambda_set_var = env.subs.fresh_unnamed_flex_var();
let this_decode_with_var = {
let subs_slice = SubsSlice::insert_into_subs(
env.subs,
[bytes_arg_var, decoder_var, fmt_arg_var],
);
let subs_slice =
env.subs
.insert_into_vars([bytes_arg_var, decoder_var, fmt_arg_var]);
let this_decode_with_var = synth_var(
env.subs,
Content::Structure(FlatType::Func(subs_slice, lambda_set_var, rec_var)),
@ -537,8 +537,7 @@ fn step_elem(
ambient_function: this_custom_callback_var,
});
let custom_callback_lambda_set_var = synth_var(env.subs, content);
let subs_slice =
SubsSlice::insert_into_subs(env.subs, [bytes_arg_var, fmt_arg_var]);
let subs_slice = env.subs.insert_into_vars([bytes_arg_var, fmt_arg_var]);
env.subs.set_content(
this_custom_callback_var,
@ -581,7 +580,7 @@ fn step_elem(
let decode_custom_var = env.import_builtin_symbol_var(Symbol::DECODE_CUSTOM);
let decode_custom_closure_var = env.subs.fresh_unnamed_flex_var();
let this_decode_custom_var = {
let subs_slice = SubsSlice::insert_into_subs(env.subs, [this_custom_callback_var]);
let subs_slice = env.subs.insert_into_vars([this_custom_callback_var]);
let flat_type =
FlatType::Func(subs_slice, decode_custom_closure_var, decode_custom_ret_var);
@ -699,7 +698,7 @@ fn step_elem(
};
{
let args_slice = SubsSlice::insert_into_subs(env.subs, [state_record_var, Variable::U64]);
let args_slice = env.subs.insert_into_vars([state_record_var, Variable::U64]);
env.subs.set_content(
function_type,
@ -884,7 +883,7 @@ fn finalizer(
};
let closure_type = synth_var(env.subs, Content::LambdaSet(lambda_set));
let flat_type = FlatType::Func(
SubsSlice::insert_into_subs(env.subs, [state_record_var]),
env.subs.insert_into_vars([state_record_var]),
closure_type,
return_type_var,
);

View file

@ -71,8 +71,7 @@ pub(crate) fn derive_to_encoder(
let flex_tag_labels = tags
.into_iter()
.map(|(label, arity)| {
let variables_slice =
VariableSubsSlice::reserve_into_subs(env.subs, arity.into());
let variables_slice = env.subs.reserve_into_vars(arity.into());
for var_index in variables_slice {
env.subs[var_index] = env.subs.fresh_unnamed_flex_var();
}
@ -114,7 +113,7 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
// List elem
let elem_var = env.subs.fresh_unnamed_flex_var();
let elem_var_slice = SubsSlice::insert_into_subs(env.subs, [elem_var]);
let elem_var_slice = env.subs.insert_into_vars([elem_var]);
let list_var = synth_var(
env.subs,
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, elem_var_slice)),
@ -205,8 +204,9 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
let encode_list_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_LIST);
// List elem, to_elem_encoder_fn_var -[clos]-> t1
let this_encode_list_args_slice =
VariableSubsSlice::insert_into_subs(env.subs, [list_var, to_elem_encoder_fn_var]);
let this_encode_list_args_slice = env
.subs
.insert_into_vars([list_var, to_elem_encoder_fn_var]);
let this_encode_list_clos_var = env.subs.fresh_unnamed_flex_var(); // clos
let this_list_encoder_var = env.subs.fresh_unnamed_flex_var(); // t1
let this_encode_list_fn_var = synth_var(
@ -266,7 +266,7 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
}),
);
// List elem -[fn_name]-> Encoder fmt
let list_var_slice = SubsSlice::insert_into_subs(env.subs, once(list_var));
let list_var_slice = env.subs.insert_into_vars(once(list_var));
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(
@ -407,7 +407,7 @@ fn to_encoder_record(
.collect::<Vec<_>>();
// typeof [ { key: .., value: .. }, { key: .., value: .. } ]
let fields_rcd_var_slice = VariableSubsSlice::insert_into_subs(env.subs, once(whole_rcd_var));
let fields_rcd_var_slice = env.subs.insert_into_vars(once(whole_rcd_var));
let fields_list_var = synth_var(
env.subs,
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, fields_rcd_var_slice)),
@ -424,8 +424,7 @@ fn to_encoder_record(
let encode_record_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_RECORD);
// fields_list_var -[clos]-> t1
let fields_list_var_slice =
VariableSubsSlice::insert_into_subs(env.subs, once(fields_list_var));
let fields_list_var_slice = env.subs.insert_into_vars(once(fields_list_var));
let encode_record_clos_var = env.subs.fresh_unnamed_flex_var(); // clos
let encoder_var = env.subs.fresh_unnamed_flex_var(); // t1
let this_encode_record_fn_var = synth_var(
@ -476,7 +475,7 @@ fn to_encoder_record(
}),
);
// typeof rcd -[fn_name]-> (typeof Encode.record [ .. ] = Encoder fmt)
let record_var_slice = SubsSlice::insert_into_subs(env.subs, once(record_var));
let record_var_slice = env.subs.insert_into_vars(once(record_var));
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(
@ -587,7 +586,7 @@ fn to_encoder_tuple(
// typeof [ toEncoder tup.0, toEncoder tup.1 ]
let whole_encoder_in_list_var_slice =
VariableSubsSlice::insert_into_subs(env.subs, once(whole_encoder_in_list_var));
env.subs.insert_into_vars(once(whole_encoder_in_list_var));
let elem_encoders_list_var = synth_var(
env.subs,
Content::Structure(FlatType::Apply(
@ -607,8 +606,7 @@ fn to_encoder_tuple(
let encode_tuple_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_TUPLE);
// elem_encoders_list_var -[clos]-> t1
let elem_encoders_list_var_slice =
VariableSubsSlice::insert_into_subs(env.subs, once(elem_encoders_list_var));
let elem_encoders_list_var_slice = env.subs.insert_into_vars(once(elem_encoders_list_var));
let encode_tuple_clos_var = env.subs.fresh_unnamed_flex_var(); // clos
let encoder_var = env.subs.fresh_unnamed_flex_var(); // t1
let this_encode_tuple_fn_var = synth_var(
@ -659,7 +657,7 @@ fn to_encoder_tuple(
}),
);
// typeof tup -[fn_name]-> (typeof Encode.tuple [ .. ] = Encoder fmt)
let tuple_var_slice = SubsSlice::insert_into_subs(env.subs, once(tuple_var));
let tuple_var_slice = env.subs.insert_into_vars(once(tuple_var));
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(
@ -746,8 +744,7 @@ fn to_encoder_tag_union(
env.import_builtin_symbol_var(Symbol::ENCODE_TO_ENCODER);
// wanted: t1 -[clos]-> t'
let var_slice_of_sym_var =
VariableSubsSlice::insert_into_subs(env.subs, [sym_var]); // [ t1 ]
let var_slice_of_sym_var = env.subs.insert_into_vars([sym_var]); // [ t1 ]
let to_encoder_clos_var = env.subs.fresh_unnamed_flex_var(); // clos
let encoder_var = env.subs.fresh_unnamed_flex_var(); // t'
let this_to_encoder_fn_var = synth_var(
@ -788,8 +785,7 @@ fn to_encoder_tag_union(
.collect();
// typeof [ Encode.toEncoder v1, Encode.toEncoder v2 ]
let whole_encoders_var_slice =
VariableSubsSlice::insert_into_subs(env.subs, [whole_payload_encoders_var]);
let whole_encoders_var_slice = env.subs.insert_into_vars([whole_payload_encoders_var]);
let payload_encoders_list_var = synth_var(
env.subs,
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, whole_encoders_var_slice)),
@ -806,10 +802,9 @@ fn to_encoder_tag_union(
let encode_tag_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_TAG);
// wanted: Str, List whole_encoders_var -[clos]-> t'
let this_encode_tag_args_var_slice = VariableSubsSlice::insert_into_subs(
env.subs,
[Variable::STR, payload_encoders_list_var],
);
let this_encode_tag_args_var_slice = env
.subs
.insert_into_vars([Variable::STR, payload_encoders_list_var]);
let this_encode_tag_clos_var = env.subs.fresh_unnamed_flex_var(); // -[clos]->
let this_encoder_var = env.subs.fresh_unnamed_flex_var(); // t'
let this_encode_tag_fn_var = synth_var(
@ -899,7 +894,7 @@ fn to_encoder_tag_union(
}),
);
// tag_union_var -[fn_name]-> whole_tag_encoders_var
let tag_union_var_slice = SubsSlice::insert_into_subs(env.subs, once(tag_union_var));
let tag_union_var_slice = env.subs.insert_into_vars(once(tag_union_var));
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(
@ -964,7 +959,8 @@ fn wrap_in_encode_custom(
// wanted: Encode.appendWith : List U8, encoder_var, fmt -[clos]-> List U8 where fmt implements EncoderFormatting
let this_append_with_args_var_slice =
VariableSubsSlice::insert_into_subs(env.subs, [Variable::LIST_U8, encoder_var, fmt_var]);
env.subs
.insert_into_vars([Variable::LIST_U8, encoder_var, fmt_var]);
let this_append_with_clos_var = env.subs.fresh_unnamed_flex_var(); // -[clos]->
let this_append_with_fn_var = synth_var(
env.subs,
@ -1018,7 +1014,7 @@ fn wrap_in_encode_custom(
);
// bytes, fmt -[[FN_name captured_var]]-> Encode.appendWith bytes encoder fmt
let args_slice = SubsSlice::insert_into_subs(env.subs, vec![bytes_var, fmt_var]);
let args_slice = env.subs.insert_into_vars(vec![bytes_var, fmt_var]);
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(args_slice, fn_clos_var, Variable::LIST_U8)),
@ -1054,7 +1050,7 @@ fn wrap_in_encode_custom(
let custom_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_CUSTOM);
// wanted: Encode.custom : fn_var -[clos]-> t'
let this_custom_args_var_slice = VariableSubsSlice::insert_into_subs(env.subs, [fn_var]);
let this_custom_args_var_slice = env.subs.insert_into_vars([fn_var]);
let this_custom_clos_var = env.subs.fresh_unnamed_flex_var(); // -[clos]->
let this_custom_encoder_var = env.subs.fresh_unnamed_flex_var(); // t'
let this_custom_fn_var = synth_var(

View file

@ -20,7 +20,7 @@ use roc_types::{
subs::{
Content, ExhaustiveMark, FlatType, GetSubsSlice, LambdaSet, OptVariable, RecordFields,
RedundantMark, Subs, SubsIndex, SubsSlice, TagExt, TupleElems, UnionLambdas, UnionTags,
Variable, VariableSubsSlice,
Variable,
},
types::RecordField,
};
@ -206,7 +206,7 @@ fn hash_tag_union(
let flex_tag_labels = tags
.into_iter()
.map(|(label, arity)| {
let variables_slice = VariableSubsSlice::reserve_into_subs(env.subs, arity.into());
let variables_slice = env.subs.reserve_into_vars(arity.into());
for var_index in variables_slice {
env.subs[var_index] = env.subs.fresh_unnamed_flex_var();
}
@ -366,7 +366,7 @@ fn hash_newtype_tag_union(
let (union_var, tag_name, payload_variables) = {
let (label, arity) = tag;
let variables_slice = VariableSubsSlice::reserve_into_subs(env.subs, arity.into());
let variables_slice = env.subs.reserve_into_vars(arity.into());
for var_index in variables_slice {
env.subs[var_index] = env.subs.fresh_unnamed_flex_var();
}
@ -466,8 +466,7 @@ fn call_hash_ability_member(
let exposed_hash_fn_var = env.import_builtin_symbol_var(member);
// (typeof body), (typeof field) -[clos]-> hasher_result
let this_arguments_slice =
VariableSubsSlice::insert_into_subs(env.subs, [in_hasher_var, in_val_var]);
let this_arguments_slice = env.subs.insert_into_vars([in_hasher_var, in_val_var]);
let this_hash_clos_var = env.subs.fresh_unnamed_flex_var();
let this_out_hasher_var = env.subs.fresh_unnamed_flex_var();
let this_hash_fn_var = synth_var(
@ -530,7 +529,7 @@ fn build_outer_derived_closure(
);
// hasher, rcd_var -[fn_name]-> (hasher = body_var)
let args_slice = SubsSlice::insert_into_subs(env.subs, [hasher_var, val_var]);
let args_slice = env.subs.insert_into_vars([hasher_var, val_var]);
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(args_slice, fn_clos_var, body_var)),

View file

@ -71,8 +71,7 @@ pub(crate) fn derive_to_inspector(
let flex_tag_labels = tags
.into_iter()
.map(|(label, arity)| {
let variables_slice =
VariableSubsSlice::reserve_into_subs(env.subs, arity.into());
let variables_slice = env.subs.reserve_into_vars(arity.into());
for var_index in variables_slice {
env.subs[var_index] = env.subs.fresh_unnamed_flex_var();
}
@ -119,7 +118,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
// List elem
let elem_var = env.subs.fresh_unnamed_flex_var();
let elem_var_slice = SubsSlice::insert_into_subs(env.subs, [elem_var]);
let elem_var_slice = env.subs.insert_into_vars([elem_var]);
let list_var = synth_var(
env.subs,
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, elem_var_slice)),
@ -212,10 +211,9 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
// List elem, List.walk, to_elem_inspector_fn_var -[clos]-> t1
let list_walk_fn_var = env.import_builtin_symbol_var(Symbol::LIST_WALK);
let this_inspect_list_args_slice = VariableSubsSlice::insert_into_subs(
env.subs,
[list_var, list_walk_fn_var, to_elem_inspector_fn_var],
);
let this_inspect_list_args_slice =
env.subs
.insert_into_vars([list_var, list_walk_fn_var, to_elem_inspector_fn_var]);
let this_inspect_list_clos_var = env.subs.fresh_unnamed_flex_var(); // clos
let this_list_inspector_var = env.subs.fresh_unnamed_flex_var(); // t1
let this_inspect_list_fn_var = synth_var(
@ -279,7 +277,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
}),
);
// List elem -[fn_name]-> Inspector fmt
let list_var_slice = SubsSlice::insert_into_subs(env.subs, once(list_var));
let list_var_slice = env.subs.insert_into_vars(once(list_var));
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(
@ -421,7 +419,7 @@ fn to_inspector_record(
.collect::<Vec<_>>();
// typeof [ { key: .., value: .. }, { key: .., value: .. } ]
let fields_rcd_var_slice = VariableSubsSlice::insert_into_subs(env.subs, once(whole_rcd_var));
let fields_rcd_var_slice = env.subs.insert_into_vars(once(whole_rcd_var));
let fields_list_var = synth_var(
env.subs,
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, fields_rcd_var_slice)),
@ -438,8 +436,7 @@ fn to_inspector_record(
let inspect_record_fn_var = env.import_builtin_symbol_var(Symbol::INSPECT_RECORD);
// fields_list_var -[clos]-> t1
let fields_list_var_slice =
VariableSubsSlice::insert_into_subs(env.subs, once(fields_list_var));
let fields_list_var_slice = env.subs.insert_into_vars(once(fields_list_var));
let inspect_record_clos_var = env.subs.fresh_unnamed_flex_var(); // clos
let inspector_var = env.subs.fresh_unnamed_flex_var(); // t1
let this_inspect_record_fn_var = synth_var(
@ -490,7 +487,7 @@ fn to_inspector_record(
}),
);
// typeof rcd -[fn_name]-> (typeof Inspect.record [ .. ] = Inspector fmt)
let record_var_slice = SubsSlice::insert_into_subs(env.subs, once(record_var));
let record_var_slice = env.subs.insert_into_vars(once(record_var));
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(
@ -602,7 +599,7 @@ fn to_inspector_tuple(
// typeof [ toInspector tup.0, toInspector tup.1 ]
let whole_inspector_in_list_var_slice =
VariableSubsSlice::insert_into_subs(env.subs, once(whole_inspector_in_list_var));
env.subs.insert_into_vars(once(whole_inspector_in_list_var));
let elem_inspectors_list_var = synth_var(
env.subs,
Content::Structure(FlatType::Apply(
@ -622,8 +619,7 @@ fn to_inspector_tuple(
let inspect_tuple_fn_var = env.import_builtin_symbol_var(Symbol::INSPECT_TUPLE);
// elem_inspectors_list_var -[clos]-> t1
let elem_inspectors_list_var_slice =
VariableSubsSlice::insert_into_subs(env.subs, once(elem_inspectors_list_var));
let elem_inspectors_list_var_slice = env.subs.insert_into_vars(once(elem_inspectors_list_var));
let inspect_tuple_clos_var = env.subs.fresh_unnamed_flex_var(); // clos
let inspector_var = env.subs.fresh_unnamed_flex_var(); // t1
let this_inspect_tuple_fn_var = synth_var(
@ -674,7 +670,7 @@ fn to_inspector_tuple(
}),
);
// typeof tup -[fn_name]-> (typeof Inspect.tuple [ .. ] = Inspector fmt)
let tuple_var_slice = SubsSlice::insert_into_subs(env.subs, once(tuple_var));
let tuple_var_slice = env.subs.insert_into_vars(once(tuple_var));
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(
@ -761,8 +757,7 @@ fn to_inspector_tag_union(
env.import_builtin_symbol_var(Symbol::INSPECT_TO_INSPECTOR);
// wanted: t1 -[clos]-> t'
let var_slice_of_sym_var =
VariableSubsSlice::insert_into_subs(env.subs, [sym_var]); // [ t1 ]
let var_slice_of_sym_var = env.subs.insert_into_vars([sym_var]); // [ t1 ]
let to_inspector_clos_var = env.subs.fresh_unnamed_flex_var(); // clos
let inspector_var = env.subs.fresh_unnamed_flex_var(); // t'
let this_to_inspector_fn_var = synth_var(
@ -804,7 +799,7 @@ fn to_inspector_tag_union(
// typeof [ Inspect.toInspector v1, Inspect.toInspector v2 ]
let whole_inspectors_var_slice =
VariableSubsSlice::insert_into_subs(env.subs, [whole_payload_inspectors_var]);
env.subs.insert_into_vars([whole_payload_inspectors_var]);
let payload_inspectors_list_var = synth_var(
env.subs,
Content::Structure(FlatType::Apply(
@ -824,10 +819,9 @@ fn to_inspector_tag_union(
let inspect_tag_fn_var = env.import_builtin_symbol_var(Symbol::INSPECT_TAG);
// wanted: Str, List whole_inspectors_var -[clos]-> t'
let this_inspect_tag_args_var_slice = VariableSubsSlice::insert_into_subs(
env.subs,
[Variable::STR, payload_inspectors_list_var],
);
let this_inspect_tag_args_var_slice = env
.subs
.insert_into_vars([Variable::STR, payload_inspectors_list_var]);
let this_inspect_tag_clos_var = env.subs.fresh_unnamed_flex_var(); // -[clos]->
let this_inspector_var = env.subs.fresh_unnamed_flex_var(); // t'
let this_inspect_tag_fn_var = synth_var(
@ -917,7 +911,7 @@ fn to_inspector_tag_union(
}),
);
// tag_union_var -[fn_name]-> whole_tag_inspectors_var
let tag_union_var_slice = SubsSlice::insert_into_subs(env.subs, once(tag_union_var));
let tag_union_var_slice = env.subs.insert_into_vars(once(tag_union_var));
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(
@ -972,8 +966,7 @@ fn wrap_in_inspect_custom(
let apply_fn_var = env.import_builtin_symbol_var(Symbol::INSPECT_APPLY);
// wanted: Inspect.apply : inspector_var, fmt -[clos]-> fmt where fmt implements InspectorFormatter
let this_apply_args_var_slice =
VariableSubsSlice::insert_into_subs(env.subs, [inspector_var, fmt_var]);
let this_apply_args_var_slice = env.subs.insert_into_vars([inspector_var, fmt_var]);
let this_apply_clos_var = env.subs.fresh_unnamed_flex_var(); // -[clos]->
let this_apply_fn_var = synth_var(
env.subs,
@ -1025,7 +1018,7 @@ fn wrap_in_inspect_custom(
);
// fmt -[[FN_name captured_var]]-> Inspect.apply inspector fmt
let args_slice = SubsSlice::insert_into_subs(env.subs, vec![fmt_var]);
let args_slice = env.subs.insert_into_vars(vec![fmt_var]);
env.subs.set_content(
fn_var,
Content::Structure(FlatType::Func(args_slice, fn_clos_var, fmt_var)),
@ -1054,7 +1047,7 @@ fn wrap_in_inspect_custom(
let custom_fn_var = env.import_builtin_symbol_var(Symbol::INSPECT_CUSTOM);
// wanted: Inspect.custom : fn_var -[clos]-> t'
let this_custom_args_var_slice = VariableSubsSlice::insert_into_subs(env.subs, [fn_var]);
let this_custom_args_var_slice = env.subs.insert_into_vars([fn_var]);
let this_custom_clos_var = env.subs.fresh_unnamed_flex_var(); // -[clos]->
let this_custom_inspector_var = env.subs.fresh_unnamed_flex_var(); // t'
let this_custom_fn_var = synth_var(

View file

@ -121,7 +121,7 @@ fn deep_copy_var_help(
macro_rules! copy_sequence {
($length:expr, $variables:expr) => {{
let new_variables = SubsSlice::reserve_into_subs(subs, $length as _);
let new_variables = subs.reserve_into_vars($length as _);
for (target_index, var_index) in (new_variables.indices()).zip($variables) {
let var = subs[var_index];
let copy_var = work!(var);
@ -134,7 +134,7 @@ fn deep_copy_var_help(
macro_rules! copy_union {
($tags:expr) => {{
let new_variable_slices = SubsSlice::reserve_variable_slices(subs, $tags.len());
let new_variable_slices = subs.reserve_variable_slices($tags.len());
let it = (new_variable_slices.indices()).zip($tags.variables());
for (target_index, index) in it {
@ -311,7 +311,7 @@ fn deep_copy_var_help(
let new_solved = copy_union!(solved);
let new_rec_var = recursion_var.map(|v| work!(v));
let new_unspecialized = SubsSlice::reserve_uls_slice(subs, unspecialized.len());
let new_unspecialized = subs.reserve_uls_slice(unspecialized.len());
for (new_uls_index, uls_index) in
(new_unspecialized.into_iter()).zip(unspecialized.into_iter())

View file

@ -329,7 +329,7 @@ pub(crate) fn type_to_var_help(
region: _,
} => {
let arguments = types.get_type_arguments(typ_index);
let new_arguments = VariableSubsSlice::reserve_into_subs(env.subs, arguments.len());
let new_arguments = env.subs.reserve_into_vars(arguments.len());
for (target_index, var_index) in
(new_arguments.indices()).zip(arguments.into_iter())
{
@ -403,7 +403,7 @@ pub(crate) fn type_to_var_help(
// This case is important for the rank of boolean variables
Function(closure_type, ret_type) => {
let arguments = types.get_type_arguments(typ_index);
let new_arguments = VariableSubsSlice::reserve_into_subs(env.subs, arguments.len());
let new_arguments = env.subs.reserve_into_vars(arguments.len());
for (target_index, var_index) in
(new_arguments.indices()).zip(arguments.into_iter())
{
@ -603,8 +603,7 @@ pub(crate) fn type_to_var_help(
let all_vars_length = type_arguments.len()
+ lambda_set_variables.len()
+ infer_ext_in_output_variables.len();
let new_variables =
VariableSubsSlice::reserve_into_subs(env.subs, all_vars_length);
let new_variables = env.subs.reserve_into_vars(all_vars_length);
let type_arguments_offset = 0;
let lambda_set_vars_offset = type_arguments_offset + type_arguments.len();
@ -704,8 +703,7 @@ pub(crate) fn type_to_var_help(
let lambda_set_vars_offset = type_arguments_offset + type_arguments.len();
let infer_ext_vars_offset = lambda_set_vars_offset + lambda_set_variables.len();
let new_variables =
VariableSubsSlice::reserve_into_subs(env.subs, all_vars_length);
let new_variables = env.subs.reserve_into_vars(all_vars_length);
for (((target_index, typ), region), abilities) in
(new_variables.indices().skip(type_arguments_offset))
@ -1025,7 +1023,7 @@ fn register_tag_arguments(
if arguments.is_empty() {
VariableSubsSlice::default()
} else {
let new_variables = VariableSubsSlice::reserve_into_subs(env.subs, arguments.len());
let new_variables = env.subs.reserve_into_vars(arguments.len());
let it = new_variables.indices().zip(arguments.into_iter());
for (target_index, argument) in it {
@ -1075,7 +1073,7 @@ fn insert_tags_fast_path(
}
}
let new_variable_slices = SubsSlice::reserve_variable_slices(env.subs, tags.len());
let new_variable_slices = env.subs.reserve_variable_slices(tags.len());
match find_tag_name_run(&types[tags], env.subs) {
Some(new_tag_names) => {
let it = (new_variable_slices.indices()).zip(payload_slices.into_iter());
@ -1089,7 +1087,7 @@ fn insert_tags_fast_path(
UnionTags::from_slices(new_tag_names, new_variable_slices)
}
None => {
let new_tag_names = SubsSlice::reserve_tag_names(env.subs, tags.len());
let new_tag_names = env.subs.reserve_tag_names(tags.len());
let it = (new_variable_slices.indices())
.zip(new_tag_names.indices())
@ -1124,7 +1122,7 @@ fn insert_tags_slow_path(
{
let tag_argument_types = &types[tag_argument_types_index];
let new_slice = VariableSubsSlice::reserve_into_subs(env.subs, tag_argument_types.len());
let new_slice = env.subs.reserve_into_vars(tag_argument_types.len());
for (i, arg) in (new_slice.indices()).zip(tag_argument_types.into_iter()) {
let var = RegisterVariable::with_stack(env, rank, arena, types, arg, stack);

View file

@ -158,11 +158,11 @@ macro_rules! v {
}
}};
(Symbol::$sym:ident $($arg:expr)*) => {{
use roc_types::subs::{Subs, SubsSlice, Content, FlatType};
use roc_types::subs::{Subs, Content, FlatType};
use roc_module::symbol::Symbol;
|subs: &mut Subs| {
let $sym = vec![ $( $arg(subs) ,)* ];
let var_slice = SubsSlice::insert_into_subs(subs, $sym);
let var_slice = subs.insert_into_vars($sym);
roc_derive::synth_var(subs, Content::Structure(FlatType::Apply(Symbol::$sym, var_slice)))
}
}};

View file

@ -20,3 +20,5 @@ ven_pretty = { path = "../../vendor/pretty" }
bumpalo.workspace = true
static_assertions.workspace = true
soa.workspace = true

View file

@ -3,17 +3,16 @@ use crate::types::{
name_type_var, AbilitySet, AliasKind, ErrorType, ExtImplicitOpenness, Polarity, RecordField,
RecordFieldsError, TupleElemsError, TypeExt, Uls,
};
use crate::unification_table::{self, UnificationTable};
use roc_collections::all::{FnvMap, ImMap, ImSet, MutSet, SendMap};
use roc_collections::{VecMap, VecSet};
use roc_error_macros::internal_error;
use roc_module::ident::{Lowercase, TagName, Uppercase};
use roc_module::symbol::{ModuleId, Symbol};
use soa::{GetSlice, Index, Slice};
use soa::{Index, Slice};
use std::fmt;
use std::iter::{once, Iterator};
use crate::unification_table::{self, UnificationTable};
// if your changes cause this number to go down, great!
// please change it to the lower number.
// if it went up, maybe check that the change is really required
@ -151,7 +150,8 @@ impl Subs {
let mut slices: Vec<SubsSlice<u8>> = Vec::new();
for field_name in lowercases {
let slice = Slice::extend_new(&mut buf, field_name.as_str().as_bytes().iter().copied());
let slice =
SubsSlice::extend_new(&mut buf, field_name.as_str().as_bytes().iter().copied());
slices.push(slice);
}
@ -170,7 +170,8 @@ impl Subs {
let mut slices: Vec<SerializedTagName> = Vec::new();
for TagName(uppercase) in tag_names {
let slice = Slice::extend_new(&mut buf, uppercase.as_str().as_bytes().iter().copied());
let slice =
SubsSlice::extend_new(&mut buf, uppercase.as_str().as_bytes().iter().copied());
let serialized = SerializedTagName(slice);
slices.push(serialized);
}
@ -412,20 +413,10 @@ impl Default for Subs {
}
/// A slice into the Vec<T> of subs
///
/// The starting position is a u32 which should be plenty
/// We limit slices to u16::MAX = 65535 elements
pub struct SubsSlice<T> {
pub start: u32,
pub length: u16,
_marker: std::marker::PhantomData<T>,
}
pub type SubsSlice<T> = Slice<Subs, T>;
/// An index into the Vec<T> of subs
pub struct SubsIndex<T> {
pub index: u32,
_marker: std::marker::PhantomData<T>,
}
pub type SubsIndex<T> = Index<Subs, T>;
// make `subs[some_index]` work. The types/trait resolution make sure we get the
// element from the right vector
@ -536,178 +527,6 @@ impl std::ops::IndexMut<SubsIndex<VariableSubsSlice>> for Subs {
}
}
// custom debug
impl<T> std::fmt::Debug for SubsIndex<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"SubsIndex<{}>({})",
std::any::type_name::<T>(),
self.index
)
}
}
impl<T> std::fmt::Debug for SubsSlice<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"SubsSlice {{ start: {}, length: {} }}",
self.start, self.length
)
}
}
// derive of copy and clone does not play well with PhantomData
impl<T> Copy for SubsIndex<T> {}
impl<T> Clone for SubsIndex<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for SubsSlice<T> {}
impl<T> Clone for SubsSlice<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Default for SubsSlice<T> {
fn default() -> Self {
Self::empty()
}
}
impl<T> SubsSlice<T> {
pub fn empty() -> Self {
Self {
start: 0,
length: 0,
_marker: Default::default(),
}
}
pub fn get_slice<'a>(&self, slice: &'a [T]) -> &'a [T] {
&slice[self.indices()]
}
pub fn get_slice_mut<'a>(&self, slice: &'a mut [T]) -> &'a mut [T] {
&mut slice[self.indices()]
}
#[inline(always)]
pub fn indices(&self) -> std::ops::Range<usize> {
self.start as usize..(self.start as usize + self.length as usize)
}
pub const fn len(&self) -> usize {
self.length as usize
}
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
pub const fn new(start: u32, length: u16) -> Self {
Self {
start,
length,
_marker: std::marker::PhantomData,
}
}
pub fn extend_new(vec: &mut Vec<T>, it: impl IntoIterator<Item = T>) -> Self {
let start = vec.len();
vec.extend(it);
let end = vec.len();
Self::new(start as u32, (end - start) as u16)
}
}
impl SubsSlice<VariableSubsSlice> {
pub fn reserve_variable_slices(subs: &mut Subs, length: usize) -> Self {
let start = subs.variable_slices.len() as u32;
subs.variable_slices.reserve(length);
let value = VariableSubsSlice::default();
for _ in 0..length {
subs.variable_slices.push(value);
}
Self::new(start, length as u16)
}
}
impl SubsSlice<TagName> {
pub fn reserve_tag_names(subs: &mut Subs, length: usize) -> Self {
let start = subs.tag_names.len() as u32;
subs.tag_names
.extend(std::iter::repeat(TagName(Uppercase::default())).take(length));
Self::new(start, length as u16)
}
}
impl SubsSlice<Uls> {
pub fn reserve_uls_slice(subs: &mut Subs, length: usize) -> Self {
let start = subs.unspecialized_lambda_sets.len() as u32;
subs.unspecialized_lambda_sets
.extend(std::iter::repeat(Uls(Variable::NULL, Symbol::UNDERSCORE, 0)).take(length));
Self::new(start, length as u16)
}
}
impl<T> SubsIndex<T> {
pub const fn new(start: u32) -> Self {
Self {
index: start,
_marker: std::marker::PhantomData,
}
}
pub fn push_new(vector: &mut Vec<T>, value: T) -> Self {
let index = Self::new(vector.len() as _);
vector.push(value);
index
}
pub const fn as_slice(self) -> SubsSlice<T> {
SubsSlice::new(self.index, 1)
}
}
impl<T> IntoIterator for SubsSlice<T> {
type Item = SubsIndex<T>;
#[allow(clippy::type_complexity)]
type IntoIter = Map<std::ops::Range<u32>, fn(u32) -> Self::Item>;
fn into_iter(self) -> Self::IntoIter {
(self.start..(self.start + self.length as u32)).map(u32_to_index)
}
}
fn u32_to_index<T>(i: u32) -> SubsIndex<T> {
SubsIndex {
index: i,
_marker: std::marker::PhantomData,
}
}
pub trait GetSubsSlice<T> {
fn get_subs_slice(&self, subs_slice: SubsSlice<T>) -> &[T];
}
@ -1794,8 +1613,7 @@ impl Subs {
))
});
let u8_slice =
VariableSubsSlice::insert_into_subs(&mut subs, std::iter::once(Variable::U8));
let u8_slice = subs.insert_into_vars(std::iter::once(Variable::U8));
subs.set_content(
Variable::LIST_U8,
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, u8_slice)),
@ -1816,6 +1634,67 @@ impl Subs {
self.utable.reserve(entries);
}
/// Reserve space for `length` variables in the subs.variables array
///
/// This is useful when we know how many variables e.g. a loop will produce,
/// but the loop itself also produces new variables. We often want to work
/// with slices, and the loop itself would break up our contiguous slice of variables
///
/// This function often helps prevent an intermediate array. See also `indices` above
/// to conveniently get a slice or iterator over the indices
pub fn reserve_into_vars(&mut self, length: usize) -> VariableSubsSlice {
let start = self.variables.len() as u32;
self.variables
.extend(std::iter::repeat(Variable::NULL).take(length));
Slice::new(start, length as u16)
}
pub fn insert_into_vars<I>(&mut self, input: I) -> VariableSubsSlice
where
I: IntoIterator<Item = Variable>,
{
let start = self.variables.len() as u32;
self.variables.extend(input);
let length = (self.variables.len() as u32 - start) as u16;
Slice::new(start, length)
}
pub fn reserve_variable_slices(&mut self, length: usize) -> SubsSlice<VariableSubsSlice> {
let start = self.variable_slices.len() as u32;
self.variable_slices.reserve(length);
let value = VariableSubsSlice::default();
for _ in 0..length {
self.variable_slices.push(value);
}
Slice::new(start, length as u16)
}
pub fn reserve_tag_names(&mut self, length: usize) -> SubsSlice<TagName> {
let start = self.tag_names.len() as u32;
self.tag_names
.extend(std::iter::repeat(TagName(Uppercase::default())).take(length));
Slice::new(start, length as u16)
}
pub fn reserve_uls_slice(&mut self, length: usize) -> SubsSlice<Uls> {
let start = self.unspecialized_lambda_sets.len() as u32;
self.unspecialized_lambda_sets
.extend(std::iter::repeat(Uls(Variable::NULL, Symbol::UNDERSCORE, 0)).take(length));
Slice::new(start, length as u16)
}
#[inline(always)]
pub fn fresh(&mut self, value: Descriptor) -> Variable {
// self.utable.new_key(value)
@ -2062,13 +1941,13 @@ impl Subs {
},
);
let new_variable_slices = SubsSlice::reserve_variable_slices(self, tags.len());
let new_variable_slices = self.reserve_variable_slices(tags.len());
let it = new_variable_slices.indices().zip(tags.iter_all());
for (variable_slice_index, (_, slice_index)) in it {
let slice = self[slice_index];
let new_variables = VariableSubsSlice::reserve_into_subs(self, slice.len());
let new_variables = self.reserve_into_vars(slice.len());
for (target_index, var_index) in new_variables.indices().zip(slice) {
let var = self[var_index];
self.variables[target_index] = self.explicit_substitute(recursive, rec_var, var);
@ -2666,38 +2545,6 @@ pub enum Builtin {
pub type VariableSubsSlice = SubsSlice<Variable>;
impl VariableSubsSlice {
/// Reserve space for `length` variables in the subs.variables array
///
/// This is useful when we know how many variables e.g. a loop will produce,
/// but the loop itself also produces new variables. We often want to work
/// with slices, and the loop itself would break up our contiguous slice of variables
///
/// This function often helps prevent an intermediate array. See also `indices` above
/// to conveniently get a slice or iterator over the indices
pub fn reserve_into_subs(subs: &mut Subs, length: usize) -> Self {
let start = subs.variables.len() as u32;
subs.variables
.extend(std::iter::repeat(Variable::NULL).take(length));
Self::new(start, length as u16)
}
pub fn insert_into_subs<I>(subs: &mut Subs, input: I) -> Self
where
I: IntoIterator<Item = Variable>,
{
let start = subs.variables.len() as u32;
subs.variables.extend(input);
let length = (subs.variables.len() as u32 - start) as u16;
Self::new(start, length)
}
}
pub trait Label: Sized + Clone {
fn index_subs(subs: &Subs, idx: SubsIndex<Self>) -> &Self;
fn get_subs_slice(subs: &Subs, slice: SubsSlice<Self>) -> &[Self];
@ -2714,15 +2561,13 @@ pub type UnionLambdas = UnionLabels<Symbol>;
impl UnionTags {
pub fn for_result(subs: &mut Subs, ok_payload: Variable, err_payload: Variable) -> Self {
let ok_tuple = {
let variables_slice =
VariableSubsSlice::insert_into_subs(subs, std::iter::once(ok_payload));
let variables_slice = subs.insert_into_vars(std::iter::once(ok_payload));
("Ok".into(), variables_slice)
};
let err_tuple = {
let variables_slice =
VariableSubsSlice::insert_into_subs(subs, std::iter::once(err_payload));
let variables_slice = subs.insert_into_vars(std::iter::once(err_payload));
("Err".into(), variables_slice)
};
@ -2857,7 +2702,7 @@ where
let mut length = 0;
for (k, v) in it {
let variables = VariableSubsSlice::insert_into_subs(subs, v.into_iter());
let variables = subs.insert_into_vars(v.into_iter());
L::push_new(subs, k);
subs.variable_slices.push(variables);
@ -4935,13 +4780,13 @@ fn storage_copy_union<L: Label>(
env: &mut StorageCopyVarToEnv<'_>,
tags: UnionLabels<L>,
) -> UnionLabels<L> {
let new_variable_slices = SubsSlice::reserve_variable_slices(env.target, tags.len());
let new_variable_slices = env.target.reserve_variable_slices(tags.len());
let it = (new_variable_slices.indices()).zip(tags.variables());
for (target_index, index) in it {
let slice = env.source[index];
let new_variables = SubsSlice::reserve_into_subs(env.target, slice.len());
let new_variables = env.target.reserve_into_vars(slice.len());
let it = (new_variables.indices()).zip(slice);
for (target_index, var_index) in it {
let var = env.source[var_index];
@ -5009,7 +4854,7 @@ fn storage_copy_var_to_help(env: &mut StorageCopyVarToEnv<'_>, var: Variable) ->
Structure(flat_type) => {
let new_flat_type = match flat_type {
Apply(symbol, arguments) => {
let new_arguments = SubsSlice::reserve_into_subs(env.target, arguments.len());
let new_arguments = env.target.reserve_into_vars(arguments.len());
for (target_index, var_index) in (new_arguments.indices()).zip(arguments) {
let var = env.source[var_index];
@ -5025,7 +4870,7 @@ fn storage_copy_var_to_help(env: &mut StorageCopyVarToEnv<'_>, var: Variable) ->
let new_closure_var = storage_copy_var_to_help(env, closure_var);
let new_arguments = SubsSlice::reserve_into_subs(env.target, arguments.len());
let new_arguments = env.target.reserve_into_vars(arguments.len());
for (target_index, var_index) in (new_arguments.indices()).zip(arguments) {
let var = env.source[var_index];
@ -5040,8 +4885,7 @@ fn storage_copy_var_to_help(env: &mut StorageCopyVarToEnv<'_>, var: Variable) ->
Record(fields, ext) => {
let record_fields = {
let new_variables =
VariableSubsSlice::reserve_into_subs(env.target, fields.len());
let new_variables = env.target.reserve_into_vars(fields.len());
let it = (new_variables.indices()).zip(fields.iter_variables());
for (target_index, var_index) in it {
@ -5075,8 +4919,7 @@ fn storage_copy_var_to_help(env: &mut StorageCopyVarToEnv<'_>, var: Variable) ->
Tuple(elems, ext) => {
let tuple_elems = {
let new_variables =
VariableSubsSlice::reserve_into_subs(env.target, elems.len());
let new_variables = env.target.reserve_into_vars(elems.len());
let it = (new_variables.indices()).zip(elems.iter_variables());
for (target_index, var_index) in it {
@ -5214,8 +5057,9 @@ fn storage_copy_var_to_help(env: &mut StorageCopyVarToEnv<'_>, var: Variable) ->
}
Alias(symbol, arguments, real_type_var, kind) => {
let new_variables =
SubsSlice::reserve_into_subs(env.target, arguments.all_variables_len as _);
let new_variables = env
.target
.reserve_into_vars(arguments.all_variables_len as _);
for (target_index, var_index) in
(new_variables.indices()).zip(arguments.all_variables())
{
@ -5248,7 +5092,7 @@ fn storage_copy_var_to_help(env: &mut StorageCopyVarToEnv<'_>, var: Variable) ->
// NB: we are only copying into storage here, not instantiating like in solve::deep_copy_var.
// So no bookkeeping should be done for the new unspecialized lambda sets.
let new_unspecialized = SubsSlice::reserve_uls_slice(env.target, unspecialized.len());
let new_unspecialized = env.target.reserve_uls_slice(unspecialized.len());
for (target_index, source_index) in
(new_unspecialized.into_iter()).zip(unspecialized.into_iter())
{
@ -5403,13 +5247,13 @@ fn copy_union<L: Label>(
max_rank: Rank,
tags: UnionLabels<L>,
) -> UnionLabels<L> {
let new_variable_slices = SubsSlice::reserve_variable_slices(env.target, tags.len());
let new_variable_slices = env.target.reserve_variable_slices(tags.len());
let it = (new_variable_slices.indices()).zip(tags.variables());
for (target_index, index) in it {
let slice = env.source[index];
let new_variables = SubsSlice::reserve_into_subs(env.target, slice.len());
let new_variables = env.target.reserve_into_vars(slice.len());
let it = (new_variables.indices()).zip(slice);
for (target_index, var_index) in it {
let var = env.source[var_index];
@ -5480,7 +5324,7 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
Structure(flat_type) => {
let new_flat_type = match flat_type {
Apply(symbol, arguments) => {
let new_arguments = SubsSlice::reserve_into_subs(env.target, arguments.len());
let new_arguments = env.target.reserve_into_vars(arguments.len());
for (target_index, var_index) in (new_arguments.indices()).zip(arguments) {
let var = env.source[var_index];
@ -5496,7 +5340,7 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
let new_closure_var = copy_import_to_help(env, max_rank, closure_var);
let new_arguments = SubsSlice::reserve_into_subs(env.target, arguments.len());
let new_arguments = env.target.reserve_into_vars(arguments.len());
for (target_index, var_index) in (new_arguments.indices()).zip(arguments) {
let var = env.source[var_index];
@ -5511,8 +5355,7 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
Record(fields, ext) => {
let record_fields = {
let new_variables =
VariableSubsSlice::reserve_into_subs(env.target, fields.len());
let new_variables = env.target.reserve_into_vars(fields.len());
let it = (new_variables.indices()).zip(fields.iter_variables());
for (target_index, var_index) in it {
@ -5546,8 +5389,7 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
Tuple(elems, ext) => {
let tuple_elems = {
let new_variables =
VariableSubsSlice::reserve_into_subs(env.target, elems.len());
let new_variables = env.target.reserve_into_vars(elems.len());
let it = (new_variables.indices()).zip(elems.iter_variables());
for (target_index, var_index) in it {
@ -5724,8 +5566,9 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
}
Alias(symbol, arguments, real_type_var, kind) => {
let new_variables =
SubsSlice::reserve_into_subs(env.target, arguments.all_variables_len as _);
let new_variables = env
.target
.reserve_into_vars(arguments.all_variables_len as _);
for (target_index, var_index) in
(new_variables.indices()).zip(arguments.all_variables())
{
@ -5757,7 +5600,7 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
let new_rec_var =
recursion_var.map(|rec_var| copy_import_to_help(env, max_rank, rec_var));
let new_unspecialized = SubsSlice::reserve_uls_slice(env.target, unspecialized.len());
let new_unspecialized = env.target.reserve_uls_slice(unspecialized.len());
for (target_index, source_index) in
(new_unspecialized.into_iter()).zip(unspecialized.into_iter())
{

View file

@ -3242,7 +3242,7 @@ fn unify_flat_type<M: MetaCollector>(
let mut outcome = unify_zip_slices(env, pool, *l_args, *r_args, ctx.mode);
if outcome.mismatches.is_empty() {
let chosen_args = SubsSlice::reserve_into_subs(env, l_args.len());
let chosen_args = env.reserve_into_vars(l_args.len());
for ((store, var1), var2) in chosen_args
.into_iter()
.zip(l_args.into_iter())