diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 35ed3e30ae..4e01e48e27 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -1,8 +1,8 @@ #![allow(clippy::manual_map)] use crate::layout::{ - Builtin, CapturesNiche, ClosureCallOptions, ClosureRepresentation, LambdaName, LambdaSet, - Layout, LayoutCache, LayoutProblem, RawFunctionLayout, TagIdIntType, UnionLayout, + Builtin, CapturesNiche, ClosureCallOptions, ClosureRepresentation, EnumDispatch, LambdaName, + LambdaSet, Layout, LayoutCache, LayoutProblem, RawFunctionLayout, TagIdIntType, UnionLayout, WrappedVariant, }; use bumpalo::collections::{CollectIn, Vec}; @@ -3269,23 +3269,10 @@ fn specialize_external<'a>( ); } - ClosureRepresentation::MultiDispatch(layout) => match layout { - Layout::Builtin(Builtin::Bool) => { - // just ignore this value, since it's not a capture - // IDEA don't pass this value in the future - } - Layout::Builtin(Builtin::Int(IntWidth::U8)) => { - // just ignore this value, since it's not a capture - // IDEA don't pass this value in the future - } - other => { - // NOTE other values always should be wrapped in a 1-element record - unreachable!( - "{:?} is not a valid closure data representation", - other - ) - } - }, + ClosureRepresentation::EnumDispatch(_) => { + // just ignore this value, since it's not a capture + // IDEA don't pass this value in the future + } } } (None, CapturedSymbols::None) | (None, CapturedSymbols::Captured([])) => {} @@ -5448,8 +5435,8 @@ where hole, ) } - ClosureRepresentation::MultiDispatch(layout) => match layout { - Layout::Builtin(Builtin::Bool) => { + ClosureRepresentation::EnumDispatch(repr) => match repr { + EnumDispatch::Bool => { debug_assert_eq!(symbols.len(), 0); debug_assert_eq!(lambda_set.set.len(), 2); @@ -5458,7 +5445,7 @@ where Stmt::Let(assigned, expr, lambda_set_layout, hole) } - Layout::Builtin(Builtin::Int(IntWidth::U8)) => { + EnumDispatch::U8 => { debug_assert_eq!(symbols.len(), 0); debug_assert!(lambda_set.set.len() > 2); @@ -5471,9 +5458,6 @@ where Stmt::Let(assigned, expr, lambda_set_layout, hole) } - layout => { - internal_error!("Invalid layout for multi-dispatch closure: {:?}", layout) - } }, }; @@ -9228,8 +9212,8 @@ where build_call(env, call, assigned, return_layout, env.arena.alloc(hole)) } - ClosureCallOptions::MultiDispatch(layout) => match layout { - Layout::Builtin(Builtin::Bool) => { + ClosureCallOptions::EnumDispatch(repr) => match repr { + EnumDispatch::Bool => { let closure_tag_id_symbol = closure_data_symbol; lowlevel_enum_lambda_set_to_switch( @@ -9245,7 +9229,7 @@ where hole, ) } - Layout::Builtin(Builtin::Int(IntWidth::U8)) => { + EnumDispatch::U8 => { let closure_tag_id_symbol = closure_data_symbol; lowlevel_enum_lambda_set_to_switch( @@ -9261,7 +9245,6 @@ where hole, ) } - other => internal_error!("Unexpected multi-dispatch layout: {:?}", other), }, } } @@ -9446,8 +9429,8 @@ fn match_on_lambda_set<'a>( hole, ) } - ClosureCallOptions::MultiDispatch(layout) => match layout { - Layout::Builtin(Builtin::Bool) => { + ClosureCallOptions::EnumDispatch(repr) => match repr { + EnumDispatch::Bool => { let closure_tag_id_symbol = closure_data_symbol; enum_lambda_set_to_switch( @@ -9462,7 +9445,7 @@ fn match_on_lambda_set<'a>( hole, ) } - Layout::Builtin(Builtin::Int(IntWidth::U8)) => { + EnumDispatch::U8 => { let closure_tag_id_symbol = closure_data_symbol; enum_lambda_set_to_switch( @@ -9477,7 +9460,6 @@ fn match_on_lambda_set<'a>( hole, ) } - other => internal_error!("Unexpected multi-dispatch layout: {:?}", other), }, } } diff --git a/crates/compiler/mono/src/layout.rs b/crates/compiler/mono/src/layout.rs index 7cb53c91ac..7bf28fd3a3 100644 --- a/crates/compiler/mono/src/layout.rs +++ b/crates/compiler/mono/src/layout.rs @@ -788,6 +788,12 @@ pub struct LambdaSet<'a> { representation: &'a Layout<'a>, } +#[derive(Debug)] +pub enum EnumDispatch { + Bool, + U8, +} + /// representation of the closure *for a particular function* #[derive(Debug)] pub enum ClosureRepresentation<'a> { @@ -804,11 +810,11 @@ pub enum ClosureRepresentation<'a> { /// /// We MUST sort these according to their stack size before code gen! AlphabeticOrderStruct(&'a [Layout<'a>]), - /// The closure dispatches to multiple functions, but none of them capture anything, so this is - /// a boolean or integer flag. - MultiDispatch(Layout<'a>), /// The closure is one function that captures a single identifier, whose value is unwrapped. UnwrappedCapture(Layout<'a>), + /// The closure dispatches to multiple functions, but none of them capture anything, so this is + /// a boolean or integer flag. + EnumDispatch(EnumDispatch), } /// How the closure should be seen when determining a call-by-name. @@ -823,10 +829,10 @@ pub enum ClosureCallOptions<'a> { field_layouts: &'a [Layout<'a>], field_order_hash: FieldOrderHash, }, - /// The closure dispatches to multiple possible functions, none of which capture. - MultiDispatch(Layout<'a>), /// The closure is one function that captures a single identifier, whose value is unwrapped. UnwrappedCapture(Layout<'a>), + /// The closure dispatches to multiple possible functions, none of which capture. + EnumDispatch(EnumDispatch), } impl<'a> LambdaSet<'a> { @@ -842,7 +848,7 @@ impl<'a> LambdaSet<'a> { pub fn is_represented(&self) -> Option> { if self.has_unwrapped_capture_repr() { Some(*self.representation) - } else if self.has_multi_dispatch_repr() { + } else if self.has_enum_dispatch_repr() { None } else { match self.representation { @@ -1036,11 +1042,13 @@ impl<'a> LambdaSet<'a> { ClosureRepresentation::AlphabeticOrderStruct(fields) } layout => { - debug_assert!( - self.has_multi_dispatch_repr(), - "Expected this to be a multi-dispatching closure, but it was something else!" - ); - ClosureRepresentation::MultiDispatch(*layout) + debug_assert!(self.has_enum_dispatch_repr(),); + let enum_repr = match layout { + Layout::Builtin(Builtin::Bool) => EnumDispatch::Bool, + Layout::Builtin(Builtin::Int(IntWidth::U8)) => EnumDispatch::U8, + other => internal_error!("Invalid layout for enum dispatch: {:?}", other), + }; + ClosureRepresentation::EnumDispatch(enum_repr) } } } @@ -1049,7 +1057,7 @@ impl<'a> LambdaSet<'a> { self.set.len() == 1 && self.set[0].1.len() == 1 } - fn has_multi_dispatch_repr(&self) -> bool { + fn has_enum_dispatch_repr(&self) -> bool { self.set.len() > 1 && self.set.iter().all(|(_, captures)| captures.is_empty()) } @@ -1077,8 +1085,13 @@ impl<'a> LambdaSet<'a> { } } layout => { - debug_assert!(self.has_multi_dispatch_repr()); - ClosureCallOptions::MultiDispatch(*layout) + debug_assert!(self.has_enum_dispatch_repr()); + let enum_repr = match layout { + Layout::Builtin(Builtin::Bool) => EnumDispatch::Bool, + Layout::Builtin(Builtin::Int(IntWidth::U8)) => EnumDispatch::U8, + other => internal_error!("Invalid layout for enum dispatch: {:?}", other), + }; + ClosureCallOptions::EnumDispatch(enum_repr) } } } @@ -1106,7 +1119,7 @@ impl<'a> LambdaSet<'a> { arguments.into_bump_slice() } - ClosureCallOptions::MultiDispatch(_) => { + ClosureCallOptions::EnumDispatch(_) => { // No captures, don't pass this along argument_layouts }