some foundations for zero-sized values in closures

This commit is contained in:
Folkert 2020-11-08 01:37:24 +01:00
parent 114e08f05f
commit 2a872f180a
4 changed files with 56 additions and 7 deletions

View file

@ -41,6 +41,15 @@ pub struct ClosureLayout<'a> {
}
impl<'a> ClosureLayout<'a> {
#[allow(dead_code)]
fn from_unit(arena: &'a Bump) -> Self {
let layout = Layout::Struct(&[]);
let layouts = arena.alloc(layout);
ClosureLayout {
captured: &[],
layout: layouts,
}
}
fn from_bool(arena: &'a Bump) -> Self {
let layout = Layout::Builtin(Builtin::Int1);
let layouts = arena.alloc(layout);
@ -111,6 +120,14 @@ impl<'a> ClosureLayout<'a> {
match variant {
Never => Ok(None),
Unit => Ok(None),
UnitWithArguments => {
// the closure layout is zero-sized, but there is something in it (e.g. `{}`)
// TODO figure out what to do in this case.
// let closure_layout = ClosureLayout::from_unit(arena);
// Ok(Some(closure_layout))
Ok(None)
}
BoolUnion { .. } => {
let closure_layout = ClosureLayout::from_bool(arena);
@ -867,6 +884,7 @@ pub fn sort_record_fields<'a>(
pub enum UnionVariant<'a> {
Never,
Unit,
UnitWithArguments,
BoolUnion { ttrue: TagName, ffalse: TagName },
ByteUnion(Vec<'a, TagName>),
Unwrapped(Vec<'a, Layout<'a>>),
@ -933,6 +951,7 @@ fn union_sorted_tags_help<'a>(
// just one tag in the union (but with arguments) can be a struct
let mut layouts = Vec::with_capacity_in(tags_vec.len(), arena);
let mut contains_zero_sized = false;
// special-case NUM_AT_NUM: if its argument is a FlexVar, make it Int
match tag_name {
@ -946,6 +965,8 @@ fn union_sorted_tags_help<'a>(
// Drop any zero-sized arguments like {}
if !layout.is_zero_sized() {
layouts.push(layout);
} else {
contains_zero_sized = true;
}
}
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
@ -962,7 +983,11 @@ fn union_sorted_tags_help<'a>(
}
if layouts.is_empty() {
UnionVariant::Unit
if contains_zero_sized {
UnionVariant::UnitWithArguments
} else {
UnionVariant::Unit
}
} else {
UnionVariant::Unwrapped(layouts)
}
@ -1045,7 +1070,7 @@ pub fn layout_from_tag_union<'a>(
match variant {
Never => panic!("TODO gracefully handle trying to instantiate Never"),
Unit => Layout::Struct(&[]),
Unit | UnitWithArguments => Layout::Struct(&[]),
BoolUnion { .. } => Layout::Builtin(Builtin::Int1),
ByteUnion(_) => Layout::Builtin(Builtin::Int8),
Unwrapped(mut field_layouts) => {