Have FunctionOrTagUnion include multiple possible tags

This commit is contained in:
Ayaz Hafiz 2022-10-03 11:01:16 -05:00
parent 797763b5fa
commit 61cf8e53e6
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
9 changed files with 155 additions and 85 deletions

View file

@ -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
))) )))
} }

View file

@ -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![]))),
// //

View file

@ -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);

View file

@ -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)
} }

View file

@ -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)
} }

View file

@ -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),
) )
} }

View file

@ -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,

View file

@ -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) => {

View file

@ -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"