mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-23 22:45:14 +00:00
Have FunctionOrTagUnion include multiple possible tags
This commit is contained in:
parent
797763b5fa
commit
61cf8e53e6
9 changed files with 155 additions and 85 deletions
|
@ -60,8 +60,6 @@ trait CopyEnv {
|
||||||
|
|
||||||
fn clone_name(&mut self, name: SubsIndex<Lowercase>) -> SubsIndex<Lowercase>;
|
fn clone_name(&mut self, name: SubsIndex<Lowercase>) -> SubsIndex<Lowercase>;
|
||||||
|
|
||||||
fn clone_tag_name(&mut self, tag_name: SubsIndex<TagName>) -> SubsIndex<TagName>;
|
|
||||||
|
|
||||||
fn clone_field_names(&mut self, field_names: SubsSlice<Lowercase>) -> SubsSlice<Lowercase>;
|
fn clone_field_names(&mut self, field_names: SubsSlice<Lowercase>) -> SubsSlice<Lowercase>;
|
||||||
|
|
||||||
fn clone_tag_names(&mut self, tag_names: SubsSlice<TagName>) -> SubsSlice<TagName>;
|
fn clone_tag_names(&mut self, tag_names: SubsSlice<TagName>) -> SubsSlice<TagName>;
|
||||||
|
@ -95,11 +93,6 @@ impl CopyEnv for Subs {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn clone_tag_name(&mut self, tag_name: SubsIndex<TagName>) -> SubsIndex<TagName> {
|
|
||||||
tag_name
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn clone_field_names(&mut self, field_names: SubsSlice<Lowercase>) -> SubsSlice<Lowercase> {
|
fn clone_field_names(&mut self, field_names: SubsSlice<Lowercase>) -> SubsSlice<Lowercase> {
|
||||||
field_names
|
field_names
|
||||||
|
@ -150,11 +143,6 @@ impl<'a> CopyEnv for AcrossSubs<'a> {
|
||||||
SubsIndex::push_new(&mut self.target.field_names, self.source[name].clone())
|
SubsIndex::push_new(&mut self.target.field_names, self.source[name].clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn clone_tag_name(&mut self, tag_name: SubsIndex<TagName>) -> SubsIndex<TagName> {
|
|
||||||
SubsIndex::push_new(&mut self.target.tag_names, self.source[tag_name].clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn clone_field_names(&mut self, field_names: SubsSlice<Lowercase>) -> SubsSlice<Lowercase> {
|
fn clone_field_names(&mut self, field_names: SubsSlice<Lowercase>) -> SubsSlice<Lowercase> {
|
||||||
SubsSlice::extend_new(
|
SubsSlice::extend_new(
|
||||||
|
@ -935,12 +923,13 @@ fn deep_copy_type_vars<C: CopyEnv>(
|
||||||
Structure(RecursiveTagUnion(new_rec_var, new_union_tags, new_ext_var))
|
Structure(RecursiveTagUnion(new_rec_var, new_union_tags, new_ext_var))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
FunctionOrTagUnion(tag_name, symbol, ext_var) => {
|
FunctionOrTagUnion(tag_names, symbols, ext_var) => {
|
||||||
let new_ext_var = descend_var!(ext_var);
|
let new_ext_var = descend_var!(ext_var);
|
||||||
let new_tag_name = env.clone_tag_name(tag_name);
|
let new_tag_names = env.clone_tag_names(tag_names);
|
||||||
|
let new_symbols = env.clone_lambda_names(symbols);
|
||||||
perform_clone!(Structure(FunctionOrTagUnion(
|
perform_clone!(Structure(FunctionOrTagUnion(
|
||||||
new_tag_name,
|
new_tag_names,
|
||||||
symbol,
|
new_symbols,
|
||||||
new_ext_var
|
new_ext_var
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use roc_module::{
|
||||||
ident::{Lowercase, TagName},
|
ident::{Lowercase, TagName},
|
||||||
symbol::Symbol,
|
symbol::Symbol,
|
||||||
};
|
};
|
||||||
use roc_types::subs::{Content, FlatType, Subs, Variable};
|
use roc_types::subs::{Content, FlatType, GetSubsSlice, Subs, Variable};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
util::{check_derivable_ext_var, debug_name_record},
|
util::{check_derivable_ext_var, debug_name_record},
|
||||||
|
@ -107,9 +107,14 @@ impl FlatEncodable {
|
||||||
|
|
||||||
Ok(Key(FlatEncodableKey::TagUnion(tag_names_and_payload_sizes)))
|
Ok(Key(FlatEncodableKey::TagUnion(tag_names_and_payload_sizes)))
|
||||||
}
|
}
|
||||||
FlatType::FunctionOrTagUnion(name_index, _, _) => Ok(Key(
|
FlatType::FunctionOrTagUnion(names_index, _, _) => {
|
||||||
FlatEncodableKey::TagUnion(vec![(subs[name_index].clone(), 0)]),
|
Ok(Key(FlatEncodableKey::TagUnion(
|
||||||
)),
|
subs.get_subs_slice(names_index)
|
||||||
|
.iter()
|
||||||
|
.map(|t| (t.clone(), 0))
|
||||||
|
.collect(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
FlatType::EmptyRecord => Ok(Key(FlatEncodableKey::Record(vec![]))),
|
FlatType::EmptyRecord => Ok(Key(FlatEncodableKey::Record(vec![]))),
|
||||||
FlatType::EmptyTagUnion => Ok(Key(FlatEncodableKey::TagUnion(vec![]))),
|
FlatType::EmptyTagUnion => Ok(Key(FlatEncodableKey::TagUnion(vec![]))),
|
||||||
//
|
//
|
||||||
|
|
|
@ -12,7 +12,7 @@ use roc_problem::can::RuntimeError;
|
||||||
use roc_target::{PtrWidth, TargetInfo};
|
use roc_target::{PtrWidth, TargetInfo};
|
||||||
use roc_types::num::NumericRange;
|
use roc_types::num::NumericRange;
|
||||||
use roc_types::subs::{
|
use roc_types::subs::{
|
||||||
self, Content, FlatType, GetSubsSlice, Label, OptVariable, RecordFields, Subs, UnionTags,
|
self, Content, FlatType, GetSubsSlice, Label, OptVariable, RecordFields, Subs,
|
||||||
UnsortedUnionLabels, Variable,
|
UnsortedUnionLabels, Variable,
|
||||||
};
|
};
|
||||||
use roc_types::types::{gather_fields_unsorted_iter, RecordField, RecordFieldsError};
|
use roc_types::types::{gather_fields_unsorted_iter, RecordField, RecordFieldsError};
|
||||||
|
@ -3152,16 +3152,18 @@ fn layout_from_flat_type<'a>(
|
||||||
|
|
||||||
layout_from_non_recursive_union(env, &tags).map(Ok)
|
layout_from_non_recursive_union(env, &tags).map(Ok)
|
||||||
}
|
}
|
||||||
FunctionOrTagUnion(tag_name, _, ext_var) => {
|
FunctionOrTagUnion(tag_names, _, ext_var) => {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
ext_var_is_empty_tag_union(subs, ext_var),
|
ext_var_is_empty_tag_union(subs, ext_var),
|
||||||
"If ext_var wasn't empty, this wouldn't be a FunctionOrTagUnion!"
|
"If ext_var wasn't empty, this wouldn't be a FunctionOrTagUnion!"
|
||||||
);
|
);
|
||||||
|
|
||||||
let union_tags = UnionTags::from_tag_name_index(tag_name);
|
let tag_names = subs.get_subs_slice(tag_names);
|
||||||
let (tags, _) = union_tags.unsorted_tags_and_ext(subs, ext_var);
|
let unsorted_tags = UnsortedUnionLabels {
|
||||||
|
tags: tag_names.iter().map(|t| (t, &[] as &[Variable])).collect(),
|
||||||
|
};
|
||||||
|
|
||||||
layout_from_non_recursive_union(env, &tags).map(Ok)
|
layout_from_non_recursive_union(env, &unsorted_tags).map(Ok)
|
||||||
}
|
}
|
||||||
RecursiveTagUnion(rec_var, tags, ext_var) => {
|
RecursiveTagUnion(rec_var, tags, ext_var) => {
|
||||||
let (tags, ext_var) = tags.unsorted_tags_and_ext(subs, ext_var);
|
let (tags, ext_var) = tags.unsorted_tags_and_ext(subs, ext_var);
|
||||||
|
|
|
@ -2299,10 +2299,11 @@ fn type_to_variable<'a>(
|
||||||
unreachable!("we assert that the ext var is empty; otherwise we'd already know it was a tag union!");
|
unreachable!("we assert that the ext var is empty; otherwise we'd already know it was a tag union!");
|
||||||
}
|
}
|
||||||
|
|
||||||
let slice = SubsIndex::new(subs.tag_names.len() as u32);
|
let tag_names = SubsSlice::extend_new(&mut subs.tag_names, [tag_name.clone()]);
|
||||||
subs.tag_names.push(tag_name.clone());
|
let symbols = SubsSlice::extend_new(&mut subs.closure_names, [*symbol]);
|
||||||
|
|
||||||
let content = Content::Structure(FlatType::FunctionOrTagUnion(slice, *symbol, ext));
|
let content =
|
||||||
|
Content::Structure(FlatType::FunctionOrTagUnion(tag_names, symbols, ext));
|
||||||
|
|
||||||
register_with_known_var(subs, destination, rank, pools, content)
|
register_with_known_var(subs, destination, rank, pools, content)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1156,11 +1156,15 @@ fn write_flat_type<'a>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionOrTagUnion(tag_name, _, ext_var) => {
|
FunctionOrTagUnion(tag_names, _, ext_var) => {
|
||||||
buf.push('[');
|
buf.push('[');
|
||||||
|
|
||||||
let mut tags: MutMap<TagName, _> = MutMap::default();
|
let mut tags: MutMap<TagName, _> = MutMap::default();
|
||||||
tags.insert(subs[*tag_name].clone(), vec![]);
|
tags.extend(
|
||||||
|
subs.get_subs_slice(*tag_names)
|
||||||
|
.iter()
|
||||||
|
.map(|t| (t.clone(), vec![])),
|
||||||
|
);
|
||||||
let ext_content = write_sorted_tags(env, ctx, subs, buf, &tags, *ext_var);
|
let ext_content = write_sorted_tags(env, ctx, subs, buf, &tags, *ext_var);
|
||||||
|
|
||||||
buf.push(']');
|
buf.push(']');
|
||||||
|
@ -1241,8 +1245,12 @@ pub fn chase_ext_tag_union(
|
||||||
push_union(subs, tags, fields);
|
push_union(subs, tags, fields);
|
||||||
chase_ext_tag_union(subs, *ext_var, fields)
|
chase_ext_tag_union(subs, *ext_var, fields)
|
||||||
}
|
}
|
||||||
Content::Structure(FunctionOrTagUnion(tag_name, _, ext_var)) => {
|
Content::Structure(FunctionOrTagUnion(tag_names, _, ext_var)) => {
|
||||||
fields.push((subs[*tag_name].clone(), vec![]));
|
fields.extend(
|
||||||
|
subs.get_subs_slice(*tag_names)
|
||||||
|
.iter()
|
||||||
|
.map(|t| (t.clone(), vec![])),
|
||||||
|
);
|
||||||
|
|
||||||
chase_ext_tag_union(subs, *ext_var, fields)
|
chase_ext_tag_union(subs, *ext_var, fields)
|
||||||
}
|
}
|
||||||
|
|
|
@ -962,13 +962,13 @@ fn subs_fmt_flat_type(this: &FlatType, subs: &Subs, f: &mut fmt::Formatter) -> f
|
||||||
|
|
||||||
write!(f, "]<{:?}>", new_ext)
|
write!(f, "]<{:?}>", new_ext)
|
||||||
}
|
}
|
||||||
FlatType::FunctionOrTagUnion(tagname_index, symbol, ext) => {
|
FlatType::FunctionOrTagUnion(tagnames, symbol, ext) => {
|
||||||
let tagname: &TagName = &subs[*tagname_index];
|
let tagnames: &[TagName] = &subs.get_subs_slice(*tagnames);
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"FunctionOrTagUnion({:?}, {:?}, {:?})",
|
"FunctionOrTagUnion({:?}, {:?}, {:?})",
|
||||||
tagname, symbol, ext
|
tagnames, symbol, ext
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
FlatType::RecursiveTagUnion(rec, tags, ext) => {
|
FlatType::RecursiveTagUnion(rec, tags, ext) => {
|
||||||
|
@ -2424,7 +2424,12 @@ pub enum FlatType {
|
||||||
Func(VariableSubsSlice, Variable, Variable),
|
Func(VariableSubsSlice, Variable, Variable),
|
||||||
Record(RecordFields, Variable),
|
Record(RecordFields, Variable),
|
||||||
TagUnion(UnionTags, Variable),
|
TagUnion(UnionTags, Variable),
|
||||||
FunctionOrTagUnion(SubsIndex<TagName>, Symbol, Variable),
|
|
||||||
|
/// `A` might either be a function
|
||||||
|
/// x -> A x : a -> [A a, B a, C a]
|
||||||
|
/// or a tag `[A, B, C]`
|
||||||
|
FunctionOrTagUnion(SubsSlice<TagName>, SubsSlice<Symbol>, Variable),
|
||||||
|
|
||||||
RecursiveTagUnion(Variable, UnionTags, Variable),
|
RecursiveTagUnion(Variable, UnionTags, Variable),
|
||||||
Erroneous(SubsIndex<Problem>),
|
Erroneous(SubsIndex<Problem>),
|
||||||
EmptyRecord,
|
EmptyRecord,
|
||||||
|
@ -3881,12 +3886,12 @@ fn flat_type_to_err_type(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionOrTagUnion(tag_name, _, ext_var) => {
|
FunctionOrTagUnion(tag_names, _, ext_var) => {
|
||||||
let tag_name = subs[tag_name].clone();
|
let tag_names = subs.get_subs_slice(tag_names);
|
||||||
|
|
||||||
let mut err_tags = SendMap::default();
|
let mut err_tags: SendMap<TagName, Vec<_>> = SendMap::default();
|
||||||
|
|
||||||
err_tags.insert(tag_name, vec![]);
|
err_tags.extend(tag_names.into_iter().map(|t| (t.clone(), vec![])));
|
||||||
|
|
||||||
match var_to_err_type(subs, state, ext_var).unwrap_structural_alias() {
|
match var_to_err_type(subs, state, ext_var).unwrap_structural_alias() {
|
||||||
ErrorType::TagUnion(sub_tags, sub_ext) => {
|
ErrorType::TagUnion(sub_tags, sub_ext) => {
|
||||||
|
@ -4202,8 +4207,8 @@ impl StorageSubs {
|
||||||
Self::offset_tag_union(offsets, *union_tags),
|
Self::offset_tag_union(offsets, *union_tags),
|
||||||
Self::offset_variable(offsets, *ext),
|
Self::offset_variable(offsets, *ext),
|
||||||
),
|
),
|
||||||
FlatType::FunctionOrTagUnion(tag_name, symbol, ext) => FlatType::FunctionOrTagUnion(
|
FlatType::FunctionOrTagUnion(tag_names, symbol, ext) => FlatType::FunctionOrTagUnion(
|
||||||
Self::offset_tag_name_index(offsets, *tag_name),
|
Self::offset_tag_name_slice(offsets, *tag_names),
|
||||||
*symbol,
|
*symbol,
|
||||||
Self::offset_variable(offsets, *ext),
|
Self::offset_variable(offsets, *ext),
|
||||||
),
|
),
|
||||||
|
@ -4295,13 +4300,13 @@ impl StorageSubs {
|
||||||
record_fields
|
record_fields
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset_tag_name_index(
|
fn offset_tag_name_slice(
|
||||||
offsets: &StorageSubsOffsets,
|
offsets: &StorageSubsOffsets,
|
||||||
mut tag_name: SubsIndex<TagName>,
|
mut tag_names: SubsSlice<TagName>,
|
||||||
) -> SubsIndex<TagName> {
|
) -> SubsSlice<TagName> {
|
||||||
tag_name.index += offsets.tag_names;
|
tag_names.start += offsets.tag_names;
|
||||||
|
|
||||||
tag_name
|
tag_names
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset_variable(offsets: &StorageSubsOffsets, variable: Variable) -> Variable {
|
fn offset_variable(offsets: &StorageSubsOffsets, variable: Variable) -> Variable {
|
||||||
|
@ -4542,12 +4547,22 @@ fn storage_copy_var_to_help(env: &mut StorageCopyVarToEnv<'_>, var: Variable) ->
|
||||||
TagUnion(union_tags, new_ext)
|
TagUnion(union_tags, new_ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionOrTagUnion(tag_name, symbol, ext_var) => {
|
FunctionOrTagUnion(tag_names, symbols, ext_var) => {
|
||||||
let new_tag_name = SubsIndex::new(env.target.tag_names.len() as u32);
|
let new_tag_names = SubsSlice::extend_new(
|
||||||
|
&mut env.target.tag_names,
|
||||||
|
env.source.get_subs_slice(tag_names).iter().cloned(),
|
||||||
|
);
|
||||||
|
|
||||||
env.target.tag_names.push(env.source[tag_name].clone());
|
let new_symbols = SubsSlice::extend_new(
|
||||||
|
&mut env.target.closure_names,
|
||||||
|
env.source.get_subs_slice(symbols).iter().cloned(),
|
||||||
|
);
|
||||||
|
|
||||||
FunctionOrTagUnion(new_tag_name, symbol, storage_copy_var_to_help(env, ext_var))
|
FunctionOrTagUnion(
|
||||||
|
new_tag_names,
|
||||||
|
new_symbols,
|
||||||
|
storage_copy_var_to_help(env, ext_var),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveTagUnion(rec_var, tags, ext_var) => {
|
RecursiveTagUnion(rec_var, tags, ext_var) => {
|
||||||
|
@ -4981,14 +4996,20 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
|
||||||
TagUnion(union_tags, new_ext)
|
TagUnion(union_tags, new_ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionOrTagUnion(tag_name, symbol, ext_var) => {
|
FunctionOrTagUnion(tag_names, symbols, ext_var) => {
|
||||||
let new_tag_name = SubsIndex::new(env.target.tag_names.len() as u32);
|
let new_tag_names = SubsSlice::extend_new(
|
||||||
|
&mut env.target.tag_names,
|
||||||
|
env.source.get_subs_slice(tag_names).iter().cloned(),
|
||||||
|
);
|
||||||
|
|
||||||
env.target.tag_names.push(env.source[tag_name].clone());
|
let new_symbols = SubsSlice::extend_new(
|
||||||
|
&mut env.target.closure_names,
|
||||||
|
env.source.get_subs_slice(symbols).iter().cloned(),
|
||||||
|
);
|
||||||
|
|
||||||
FunctionOrTagUnion(
|
FunctionOrTagUnion(
|
||||||
new_tag_name,
|
new_tag_names,
|
||||||
symbol,
|
new_symbols,
|
||||||
copy_import_to_help(env, max_rank, ext_var),
|
copy_import_to_help(env, max_rank, ext_var),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2657,13 +2657,13 @@ fn unify_flat_type<M: MetaCollector>(
|
||||||
|
|
||||||
outcome
|
outcome
|
||||||
}
|
}
|
||||||
(FunctionOrTagUnion(tag_name, tag_symbol, ext), Func(args, closure, ret)) => {
|
(FunctionOrTagUnion(tag_names, tag_symbols, ext), Func(args, closure, ret)) => {
|
||||||
unify_function_or_tag_union_and_func(
|
unify_function_or_tag_union_and_func(
|
||||||
env,
|
env,
|
||||||
pool,
|
pool,
|
||||||
ctx,
|
ctx,
|
||||||
tag_name,
|
*tag_names,
|
||||||
*tag_symbol,
|
*tag_symbols,
|
||||||
*ext,
|
*ext,
|
||||||
*args,
|
*args,
|
||||||
*ret,
|
*ret,
|
||||||
|
@ -2671,13 +2671,13 @@ fn unify_flat_type<M: MetaCollector>(
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
(Func(args, closure, ret), FunctionOrTagUnion(tag_name, tag_symbol, ext)) => {
|
(Func(args, closure, ret), FunctionOrTagUnion(tag_names, tag_symbols, ext)) => {
|
||||||
unify_function_or_tag_union_and_func(
|
unify_function_or_tag_union_and_func(
|
||||||
env,
|
env,
|
||||||
pool,
|
pool,
|
||||||
ctx,
|
ctx,
|
||||||
tag_name,
|
*tag_names,
|
||||||
*tag_symbol,
|
*tag_symbols,
|
||||||
*ext,
|
*ext,
|
||||||
*args,
|
*args,
|
||||||
*ret,
|
*ret,
|
||||||
|
@ -2685,9 +2685,9 @@ fn unify_flat_type<M: MetaCollector>(
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
(FunctionOrTagUnion(tag_name_1, _, ext1), FunctionOrTagUnion(tag_name_2, _, ext2)) => {
|
(FunctionOrTagUnion(tag_names_1, _, ext1), FunctionOrTagUnion(tag_names_2, _, ext2)) => {
|
||||||
let tag_name_1_ref = &env.subs[*tag_name_1];
|
let tag_name_1_ref = &env.subs.get_subs_slice(*tag_names_1);
|
||||||
let tag_name_2_ref = &env.subs[*tag_name_2];
|
let tag_name_2_ref = &env.subs.get_subs_slice(*tag_names_2);
|
||||||
|
|
||||||
if tag_name_1_ref == tag_name_2_ref {
|
if tag_name_1_ref == tag_name_2_ref {
|
||||||
let outcome = unify_pool(env, pool, *ext1, *ext2, ctx.mode);
|
let outcome = unify_pool(env, pool, *ext1, *ext2, ctx.mode);
|
||||||
|
@ -2698,37 +2698,62 @@ fn unify_flat_type<M: MetaCollector>(
|
||||||
outcome
|
outcome
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let tags1 = UnionTags::from_tag_name_index(*tag_name_1);
|
let empty_tag_var_slices_1 = SubsSlice::extend_new(
|
||||||
let tags2 = UnionTags::from_tag_name_index(*tag_name_2);
|
&mut env.subs.variable_slices,
|
||||||
|
std::iter::repeat(Default::default()).take(tag_names_1.len()),
|
||||||
|
);
|
||||||
|
let tags1 = UnionTags::from_slices(*tag_names_1, empty_tag_var_slices_1);
|
||||||
|
|
||||||
|
let empty_tag_var_slices_2 = SubsSlice::extend_new(
|
||||||
|
&mut env.subs.variable_slices,
|
||||||
|
std::iter::repeat(Default::default()).take(tag_names_2.len()),
|
||||||
|
);
|
||||||
|
let tags2 = UnionTags::from_slices(*tag_names_2, empty_tag_var_slices_2);
|
||||||
|
|
||||||
unify_tag_unions(env, pool, ctx, tags1, *ext1, tags2, *ext2, Rec::None)
|
unify_tag_unions(env, pool, ctx, tags1, *ext1, tags2, *ext2, Rec::None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(TagUnion(tags1, ext1), FunctionOrTagUnion(tag_name, _, ext2)) => {
|
(TagUnion(tags1, ext1), FunctionOrTagUnion(tag_names, _, ext2)) => {
|
||||||
let tags2 = UnionTags::from_tag_name_index(*tag_name);
|
let empty_tag_var_slices = SubsSlice::extend_new(
|
||||||
|
&mut env.subs.variable_slices,
|
||||||
|
std::iter::repeat(Default::default()).take(tag_names.len()),
|
||||||
|
);
|
||||||
|
let tags2 = UnionTags::from_slices(*tag_names, empty_tag_var_slices);
|
||||||
|
|
||||||
unify_tag_unions(env, pool, ctx, *tags1, *ext1, tags2, *ext2, Rec::None)
|
unify_tag_unions(env, pool, ctx, *tags1, *ext1, tags2, *ext2, Rec::None)
|
||||||
}
|
}
|
||||||
(FunctionOrTagUnion(tag_name, _, ext1), TagUnion(tags2, ext2)) => {
|
(FunctionOrTagUnion(tag_names, _, ext1), TagUnion(tags2, ext2)) => {
|
||||||
let tags1 = UnionTags::from_tag_name_index(*tag_name);
|
let empty_tag_var_slices = SubsSlice::extend_new(
|
||||||
|
&mut env.subs.variable_slices,
|
||||||
|
std::iter::repeat(Default::default()).take(tag_names.len()),
|
||||||
|
);
|
||||||
|
let tags1 = UnionTags::from_slices(*tag_names, empty_tag_var_slices);
|
||||||
|
|
||||||
unify_tag_unions(env, pool, ctx, tags1, *ext1, *tags2, *ext2, Rec::None)
|
unify_tag_unions(env, pool, ctx, tags1, *ext1, *tags2, *ext2, Rec::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
(RecursiveTagUnion(recursion_var, tags1, ext1), FunctionOrTagUnion(tag_name, _, ext2)) => {
|
(RecursiveTagUnion(recursion_var, tags1, ext1), FunctionOrTagUnion(tag_names, _, ext2)) => {
|
||||||
// this never happens in type-correct programs, but may happen if there is a type error
|
// this never happens in type-correct programs, but may happen if there is a type error
|
||||||
debug_assert!(is_recursion_var(env.subs, *recursion_var));
|
debug_assert!(is_recursion_var(env.subs, *recursion_var));
|
||||||
|
|
||||||
let tags2 = UnionTags::from_tag_name_index(*tag_name);
|
let empty_tag_var_slices = SubsSlice::extend_new(
|
||||||
|
&mut env.subs.variable_slices,
|
||||||
|
std::iter::repeat(Default::default()).take(tag_names.len()),
|
||||||
|
);
|
||||||
|
let tags2 = UnionTags::from_slices(*tag_names, empty_tag_var_slices);
|
||||||
let rec = Rec::Left(*recursion_var);
|
let rec = Rec::Left(*recursion_var);
|
||||||
|
|
||||||
unify_tag_unions(env, pool, ctx, *tags1, *ext1, tags2, *ext2, rec)
|
unify_tag_unions(env, pool, ctx, *tags1, *ext1, tags2, *ext2, rec)
|
||||||
}
|
}
|
||||||
|
|
||||||
(FunctionOrTagUnion(tag_name, _, ext1), RecursiveTagUnion(recursion_var, tags2, ext2)) => {
|
(FunctionOrTagUnion(tag_names, _, ext1), RecursiveTagUnion(recursion_var, tags2, ext2)) => {
|
||||||
debug_assert!(is_recursion_var(env.subs, *recursion_var));
|
debug_assert!(is_recursion_var(env.subs, *recursion_var));
|
||||||
|
|
||||||
let tags1 = UnionTags::from_tag_name_index(*tag_name);
|
let empty_tag_var_slices = SubsSlice::extend_new(
|
||||||
|
&mut env.subs.variable_slices,
|
||||||
|
std::iter::repeat(Default::default()).take(tag_names.len()),
|
||||||
|
);
|
||||||
|
let tags1 = UnionTags::from_slices(*tag_names, empty_tag_var_slices);
|
||||||
let rec = Rec::Right(*recursion_var);
|
let rec = Rec::Right(*recursion_var);
|
||||||
|
|
||||||
unify_tag_unions(env, pool, ctx, tags1, *ext1, *tags2, *ext2, rec)
|
unify_tag_unions(env, pool, ctx, tags1, *ext1, *tags2, *ext2, rec)
|
||||||
|
@ -3133,17 +3158,20 @@ fn unify_function_or_tag_union_and_func<M: MetaCollector>(
|
||||||
env: &mut Env,
|
env: &mut Env,
|
||||||
pool: &mut Pool,
|
pool: &mut Pool,
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
tag_name_index: &SubsIndex<TagName>,
|
tag_names_slice: SubsSlice<TagName>,
|
||||||
tag_symbol: Symbol,
|
tag_fn_lambdas: SubsSlice<Symbol>,
|
||||||
tag_ext: Variable,
|
tag_ext: Variable,
|
||||||
function_arguments: VariableSubsSlice,
|
function_arguments: VariableSubsSlice,
|
||||||
function_return: Variable,
|
function_return: Variable,
|
||||||
function_lambda_set: Variable,
|
function_lambda_set: Variable,
|
||||||
left: bool,
|
left: bool,
|
||||||
) -> Outcome<M> {
|
) -> Outcome<M> {
|
||||||
let tag_name = env.subs[*tag_name_index].clone();
|
let tag_names = env.subs.get_subs_slice(tag_names_slice).to_vec();
|
||||||
|
|
||||||
let union_tags = UnionTags::insert_slices_into_subs(env.subs, [(tag_name, function_arguments)]);
|
let union_tags = UnionTags::insert_slices_into_subs(
|
||||||
|
env.subs,
|
||||||
|
tag_names.into_iter().map(|tag| (tag, function_arguments)),
|
||||||
|
);
|
||||||
let content = Content::Structure(FlatType::TagUnion(union_tags, tag_ext));
|
let content = Content::Structure(FlatType::TagUnion(union_tags, tag_ext));
|
||||||
|
|
||||||
let new_tag_union_var = fresh(env, pool, ctx, content);
|
let new_tag_union_var = fresh(env, pool, ctx, content);
|
||||||
|
@ -3155,7 +3183,14 @@ fn unify_function_or_tag_union_and_func<M: MetaCollector>(
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
let union_tags = UnionLambdas::tag_without_arguments(env.subs, tag_symbol);
|
let lambda_names = env.subs.get_subs_slice(tag_fn_lambdas).to_vec();
|
||||||
|
let new_lambda_names = SubsSlice::extend_new(&mut env.subs.closure_names, lambda_names);
|
||||||
|
let empty_captures_slices = SubsSlice::extend_new(
|
||||||
|
&mut env.subs.variable_slices,
|
||||||
|
std::iter::repeat(Default::default()).take(new_lambda_names.len()),
|
||||||
|
);
|
||||||
|
let union_tags = UnionLambdas::from_slices(new_lambda_names, empty_captures_slices);
|
||||||
|
|
||||||
let ambient_function_var = if left { ctx.first } else { ctx.second };
|
let ambient_function_var = if left { ctx.first } else { ctx.second };
|
||||||
let lambda_set_content = LambdaSet(self::LambdaSet {
|
let lambda_set_content = LambdaSet(self::LambdaSet {
|
||||||
solved: union_tags,
|
solved: union_tags,
|
||||||
|
|
|
@ -450,8 +450,8 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
||||||
payload_vars,
|
payload_vars,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
Content::Structure(FlatType::FunctionOrTagUnion(tag_name, _, _)) => {
|
Content::Structure(FlatType::FunctionOrTagUnion(tag_names, _, _)) => {
|
||||||
let tag_name = &env.subs[*tag_name];
|
let tag_name = &env.subs.get_subs_slice(*tag_names)[0];
|
||||||
|
|
||||||
Ok(single_tag_union_to_ast(
|
Ok(single_tag_union_to_ast(
|
||||||
env,
|
env,
|
||||||
|
@ -631,8 +631,8 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
||||||
let (tag_name, payload_vars) = unpack_single_element_tag_union(env.subs, *tags);
|
let (tag_name, payload_vars) = unpack_single_element_tag_union(env.subs, *tags);
|
||||||
single_tag_union_to_ast(env, mem, addr, field_layouts, tag_name, payload_vars)
|
single_tag_union_to_ast(env, mem, addr, field_layouts, tag_name, payload_vars)
|
||||||
}
|
}
|
||||||
Content::Structure(FlatType::FunctionOrTagUnion(tag_name, _, _)) => {
|
Content::Structure(FlatType::FunctionOrTagUnion(tag_names, _, _)) => {
|
||||||
let tag_name = &env.subs[*tag_name];
|
let tag_name = &env.subs.get_subs_slice(*tag_names)[0];
|
||||||
single_tag_union_to_ast(env, mem, addr, field_layouts, tag_name, &[])
|
single_tag_union_to_ast(env, mem, addr, field_layouts, tag_name, &[])
|
||||||
}
|
}
|
||||||
Content::Structure(FlatType::EmptyRecord) => {
|
Content::Structure(FlatType::EmptyRecord) => {
|
||||||
|
|
|
@ -3,4 +3,13 @@ app "helloWorld"
|
||||||
imports []
|
imports []
|
||||||
provides [main] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main = "Hello, World!\n"
|
crash : Str -> a
|
||||||
|
crash = \msg ->
|
||||||
|
expect msg != msg
|
||||||
|
|
||||||
|
diverge : {} -> a
|
||||||
|
diverge = \{} -> diverge {}
|
||||||
|
|
||||||
|
diverge {}
|
||||||
|
|
||||||
|
main = crash "Hello, World!\n"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue