mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 20:28:02 +00:00
Low-level to extract discriminant from a tag union
This commit is contained in:
parent
7421485973
commit
fd54cdfdd1
6 changed files with 41 additions and 4 deletions
|
@ -84,6 +84,7 @@ macro_rules! map_symbol_to_lowlevel_and_arity {
|
|||
LowLevel::PtrCast => unimplemented!(),
|
||||
LowLevel::RefCountInc => unimplemented!(),
|
||||
LowLevel::RefCountDec => unimplemented!(),
|
||||
LowLevel::TagDiscriminant => unimplemented!(),
|
||||
|
||||
// these are not implemented, not sure why
|
||||
LowLevel::StrFromInt => unimplemented!(),
|
||||
|
|
|
@ -6575,7 +6575,7 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
unreachable!("these are higher order, and are handled elsewhere")
|
||||
}
|
||||
|
||||
BoxExpr | UnboxExpr => {
|
||||
BoxExpr | UnboxExpr | TagDiscriminant => {
|
||||
unreachable!("The {:?} operation is turned into mono Expr", op)
|
||||
}
|
||||
|
||||
|
|
|
@ -1856,7 +1856,7 @@ impl<'a> LowLevelCall<'a> {
|
|||
|
||||
Eq | NotEq => self.eq_or_neq(backend),
|
||||
|
||||
BoxExpr | UnboxExpr => {
|
||||
BoxExpr | UnboxExpr | TagDiscriminant => {
|
||||
unreachable!("The {:?} operation is turned into mono Expr", self.lowlevel)
|
||||
}
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ pub enum LowLevel {
|
|||
BoxExpr,
|
||||
UnboxExpr,
|
||||
Unreachable,
|
||||
TagDiscriminant,
|
||||
}
|
||||
|
||||
macro_rules! higher_order {
|
||||
|
@ -211,12 +212,12 @@ macro_rules! map_symbol_to_lowlevel {
|
|||
LowLevel::PtrCast => unimplemented!(),
|
||||
LowLevel::RefCountInc => unimplemented!(),
|
||||
LowLevel::RefCountDec => unimplemented!(),
|
||||
LowLevel::TagDiscriminant => unimplemented!(),
|
||||
|
||||
// these are not implemented, not sure why
|
||||
LowLevel::StrFromInt => unimplemented!(),
|
||||
LowLevel::StrFromFloat => unimplemented!(),
|
||||
LowLevel::NumIsFinite => unimplemented!(),
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -935,7 +935,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
|||
|
||||
ListIsUnique => arena.alloc_slice_copy(&[borrowed]),
|
||||
|
||||
BoxExpr | UnboxExpr => {
|
||||
BoxExpr | UnboxExpr | TagDiscriminant => {
|
||||
unreachable!("These lowlevel operations are turned into mono Expr's")
|
||||
}
|
||||
|
||||
|
|
|
@ -5444,6 +5444,41 @@ pub fn with_hole<'a>(
|
|||
|
||||
Stmt::Let(assigned, Expr::ExprUnbox { symbol: x }, layout, hole)
|
||||
}
|
||||
TagDiscriminant => {
|
||||
debug_assert_eq!(arg_symbols.len(), 1);
|
||||
let x = arg_symbols[0];
|
||||
let x_layout = layout_cache.from_var(arena, args[0].0, env.subs).expect(
|
||||
"TagDiscriminant only built in derived impls, which must type-check",
|
||||
);
|
||||
|
||||
let x_union_layout = match x_layout {
|
||||
Layout::Union(un) => un,
|
||||
_ => internal_error!("TagDiscriminant can only apply to tags"),
|
||||
};
|
||||
let tag_id_layout = x_union_layout.tag_id_layout();
|
||||
debug_assert!(tag_id_layout == Layout::u8() || tag_id_layout == Layout::u16());
|
||||
|
||||
let tag_id_sym = env.unique_symbol();
|
||||
|
||||
let cast_to_u16 = self::Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::NumIntCast,
|
||||
update_mode: env.next_update_mode_id(),
|
||||
},
|
||||
arguments: env.arena.alloc([tag_id_sym]),
|
||||
};
|
||||
|
||||
let hole = Stmt::Let(assigned, Expr::Call(cast_to_u16), Layout::u16(), hole);
|
||||
Stmt::Let(
|
||||
tag_id_sym,
|
||||
Expr::GetTagId {
|
||||
structure: x,
|
||||
union_layout: x_union_layout,
|
||||
},
|
||||
tag_id_layout,
|
||||
env.arena.alloc(hole),
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
let call = self::Call {
|
||||
call_type: CallType::LowLevel {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue