diff --git a/bindgen/src/bindgen.rs b/bindgen/src/bindgen.rs index 7bd9b90903..9803f74dec 100644 --- a/bindgen/src/bindgen.rs +++ b/bindgen/src/bindgen.rs @@ -1,6 +1,9 @@ use crate::structs::Structs; use crate::types::{RocTagUnion, TypeId, Types}; -use crate::{enums::Enums, types::RocType}; +use crate::{ + enums::Enums, + types::{RocNum, RocType}, +}; use bumpalo::Bump; use roc_builtins::bitcode::{FloatWidth::*, IntWidth::*}; use roc_collections::VecMap; @@ -188,24 +191,24 @@ fn add_builtin_type<'a>( ) -> TypeId { match builtin { Builtin::Int(width) => match width { - U8 => types.add(RocType::U8), - U16 => types.add(RocType::U16), - U32 => types.add(RocType::U32), - U64 => types.add(RocType::U64), - U128 => types.add(RocType::U128), - I8 => types.add(RocType::I8), - I16 => types.add(RocType::I16), - I32 => types.add(RocType::I32), - I64 => types.add(RocType::I64), - I128 => types.add(RocType::I128), + U8 => types.add(RocType::Num(RocNum::U8)), + U16 => types.add(RocType::Num(RocNum::U16)), + U32 => types.add(RocType::Num(RocNum::U32)), + U64 => types.add(RocType::Num(RocNum::U64)), + U128 => types.add(RocType::Num(RocNum::U128)), + I8 => types.add(RocType::Num(RocNum::I8)), + I16 => types.add(RocType::Num(RocNum::I16)), + I32 => types.add(RocType::Num(RocNum::I32)), + I64 => types.add(RocType::Num(RocNum::I64)), + I128 => types.add(RocType::Num(RocNum::I128)), }, Builtin::Float(width) => match width { - F32 => types.add(RocType::F32), - F64 => types.add(RocType::F64), - F128 => types.add(RocType::F128), + F32 => types.add(RocType::Num(RocNum::F32)), + F64 => types.add(RocType::Num(RocNum::F64)), + F128 => types.add(RocType::Num(RocNum::F128)), }, + Builtin::Decimal => types.add(RocType::Num(RocNum::Dec)), Builtin::Bool => types.add(RocType::Bool), - Builtin::Decimal => types.add(RocType::RocDec), Builtin::Str => types.add(RocType::RocStr), Builtin::Dict(key_layout, val_layout) => { // TODO FIXME this `var` is wrong - should have a different `var` for key and for val diff --git a/bindgen/src/bindgen_rs.rs b/bindgen/src/bindgen_rs.rs index 733e59de67..11848bc50a 100644 --- a/bindgen/src/bindgen_rs.rs +++ b/bindgen/src/bindgen_rs.rs @@ -1,4 +1,4 @@ -use crate::types::{RocTagUnion, RocType, TypeId, Types}; +use crate::types::{RocNum, RocTagUnion, RocType, TypeId, Types}; use indexmap::IndexMap; use roc_mono::layout::UnionLayout; use roc_target::Architecture; @@ -203,21 +203,8 @@ fn add_type(architecture: Architecture, id: TypeId, types: &Types, impls: &mut I } } // These types don't need to be declared in Rust. - RocType::U8 - | RocType::U16 - | RocType::U32 - | RocType::U64 - | RocType::U128 - | RocType::I8 - | RocType::I16 - | RocType::I32 - | RocType::I64 - | RocType::I128 - | RocType::F32 - | RocType::F64 - | RocType::F128 + RocType::Num(_) | RocType::Bool - | RocType::RocDec | RocType::RocStr | RocType::RocDict(_, _) | RocType::RocSet(_) @@ -552,20 +539,7 @@ pub struct {name} {{ match payload_type { RocType::RocStr | RocType::Bool - | RocType::I8 - | RocType::U8 - | RocType::I16 - | RocType::U16 - | RocType::I32 - | RocType::U32 - | RocType::I64 - | RocType::U64 - | RocType::I128 - | RocType::U128 - | RocType::F32 - | RocType::F64 - | RocType::F128 - | RocType::RocDec + | RocType::Num(_) | RocType::RocList(_) | RocType::RocDict(_, _) | RocType::RocSet(_) @@ -1065,20 +1039,7 @@ pub struct {name} {{ let fields_str = match payload_type { RocType::RocStr | RocType::Bool - | RocType::I8 - | RocType::U8 - | RocType::I16 - | RocType::U16 - | RocType::I32 - | RocType::U32 - | RocType::I64 - | RocType::U64 - | RocType::I128 - | RocType::U128 - | RocType::F32 - | RocType::F64 - | RocType::F128 - | RocType::RocDec + | RocType::Num(_) | RocType::RocList(_) | RocType::RocDict(_, _) | RocType::RocSet(_) @@ -1232,22 +1193,22 @@ fn add_struct( fn type_name(id: TypeId, types: &Types) -> String { match types.get(id) { - RocType::U8 => "u8".to_string(), - RocType::U16 => "u16".to_string(), - RocType::U32 => "u32".to_string(), - RocType::U64 => "u64".to_string(), - RocType::U128 => "roc_std::U128".to_string(), - RocType::I8 => "i8".to_string(), - RocType::I16 => "i16".to_string(), - RocType::I32 => "i32".to_string(), - RocType::I64 => "i64".to_string(), - RocType::I128 => "roc_std::I128".to_string(), - RocType::F32 => "f32".to_string(), - RocType::F64 => "f64".to_string(), - RocType::F128 => "roc_std::F128".to_string(), - RocType::Bool => "bool".to_string(), - RocType::RocDec => "roc_std::RocDec".to_string(), RocType::RocStr => "roc_std::RocStr".to_string(), + RocType::Bool => "bool".to_string(), + RocType::Num(RocNum::U8) => "u8".to_string(), + RocType::Num(RocNum::U16) => "u16".to_string(), + RocType::Num(RocNum::U32) => "u32".to_string(), + RocType::Num(RocNum::U64) => "u64".to_string(), + RocType::Num(RocNum::U128) => "roc_std::U128".to_string(), + RocType::Num(RocNum::I8) => "i8".to_string(), + RocType::Num(RocNum::I16) => "i16".to_string(), + RocType::Num(RocNum::I32) => "i32".to_string(), + RocType::Num(RocNum::I64) => "i64".to_string(), + RocType::Num(RocNum::I128) => "roc_std::I128".to_string(), + RocType::Num(RocNum::F32) => "f32".to_string(), + RocType::Num(RocNum::F64) => "f64".to_string(), + RocType::Num(RocNum::F128) => "roc_std::F128".to_string(), + RocType::Num(RocNum::Dec) => "roc_std::RocDec".to_string(), RocType::RocDict(key_id, val_id) => format!( "roc_std::RocDict<{}, {}>", type_name(*key_id, types), diff --git a/bindgen/src/types.rs b/bindgen/src/types.rs index f66f9dc309..47bf2ae6cd 100644 --- a/bindgen/src/types.rs +++ b/bindgen/src/types.rs @@ -124,20 +124,7 @@ impl<'a> Iterator for TypesIter<'a> { pub enum RocType { RocStr, Bool, - I8, - U8, - I16, - U16, - I32, - U32, - I64, - U64, - I128, - U128, - F32, - F64, - F128, - RocDec, + Num(RocNum), RocList(TypeId), RocDict(TypeId, TypeId), RocSet(TypeId), @@ -158,26 +145,76 @@ pub enum RocType { RecursivePointer(TypeId), } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum RocNum { + I8, + U8, + I16, + U16, + I32, + U32, + I64, + U64, + I128, + U128, + F32, + F64, + F128, + Dec, +} + +impl RocNum { + fn size(&self) -> usize { + use core::mem::size_of; + use RocNum::*; + + match self { + I8 => size_of::(), + U8 => size_of::(), + I16 => size_of::(), + U16 => size_of::(), + I32 => size_of::(), + U32 => size_of::(), + I64 => size_of::(), + U64 => size_of::(), + I128 => size_of::(), + U128 => size_of::(), + F32 => size_of::(), + F64 => size_of::(), + F128 => todo!(), + Dec => size_of::(), + } + } + + fn alignment(&self, target_info: TargetInfo) -> usize { + use RocNum::*; + + match self { + I8 => IntWidth::I8.alignment_bytes(target_info) as usize, + U8 => IntWidth::U8.alignment_bytes(target_info) as usize, + I16 => IntWidth::I16.alignment_bytes(target_info) as usize, + U16 => IntWidth::U16.alignment_bytes(target_info) as usize, + I32 => IntWidth::I32.alignment_bytes(target_info) as usize, + U32 => IntWidth::U32.alignment_bytes(target_info) as usize, + I64 => IntWidth::I64.alignment_bytes(target_info) as usize, + U64 => IntWidth::U64.alignment_bytes(target_info) as usize, + I128 => IntWidth::I128.alignment_bytes(target_info) as usize, + U128 => IntWidth::U128.alignment_bytes(target_info) as usize, + F32 => FloatWidth::F32.alignment_bytes(target_info) as usize, + F64 => FloatWidth::F64.alignment_bytes(target_info) as usize, + F128 => FloatWidth::F128.alignment_bytes(target_info) as usize, + Dec => align_of::(), + } + } +} + impl RocType { /// Useful when determining whether to derive Copy in a Rust type. pub fn has_pointer(&self, types: &Types) -> bool { match self { RocType::Bool - | RocType::I8 - | RocType::U8 - | RocType::I16 - | RocType::U16 - | RocType::I32 - | RocType::U32 - | RocType::I64 - | RocType::U64 - | RocType::I128 - | RocType::U128 - | RocType::F32 - | RocType::F64 - | RocType::F128 - | RocType::TagUnion(RocTagUnion::Enumeration { .. }) - | RocType::RocDec => false, + | RocType::Num(_) + | RocType::TagUnion(RocTagUnion::Enumeration { .. }) => false, RocType::RocStr | RocType::RocList(_) | RocType::RocDict(_, _) @@ -205,20 +242,16 @@ impl RocType { fn has_float_help(&self, types: &Types, do_not_recurse: &[TypeId]) -> bool { match self { - RocType::F32 | RocType::F64 | RocType::F128 => true, + RocType::Num(num) => { + use RocNum::*; + + match num { + F32 | F64 | F128 => true, + I8 | U8 | I16 | U16 | I32 | U32 | I64 | U64 | I128 | U128 | Dec => false, + } + } RocType::RocStr | RocType::Bool - | RocType::I8 - | RocType::U8 - | RocType::I16 - | RocType::U16 - | RocType::I32 - | RocType::U32 - | RocType::I64 - | RocType::U64 - | RocType::I128 - | RocType::U128 - | RocType::RocDec | RocType::TagUnion(RocTagUnion::Enumeration { .. }) => false, RocType::RocList(id) | RocType::RocSet(id) | RocType::RocBox(id) => { types.get(*id).has_float_help(types, do_not_recurse) @@ -269,22 +302,7 @@ impl RocType { pub fn has_enumeration(&self, types: &Types) -> bool { match self { RocType::TagUnion { .. } | RocType::RecursivePointer { .. } => true, - RocType::RocStr - | RocType::Bool - | RocType::I8 - | RocType::U8 - | RocType::I16 - | RocType::U16 - | RocType::I32 - | RocType::U32 - | RocType::I64 - | RocType::U64 - | RocType::I128 - | RocType::U128 - | RocType::F32 - | RocType::F64 - | RocType::F128 - | RocType::RocDec => false, + RocType::RocStr | RocType::Bool | RocType::Num(_) => false, RocType::RocList(id) | RocType::RocSet(id) | RocType::RocBox(id) => { types.get(*id).has_enumeration(types) } @@ -306,20 +324,7 @@ impl RocType { match self { RocType::Bool => size_of::(), - RocType::I8 => size_of::(), - RocType::U8 => size_of::(), - RocType::I16 => size_of::(), - RocType::U16 => size_of::(), - RocType::I32 => size_of::(), - RocType::U32 => size_of::(), - RocType::I64 => size_of::(), - RocType::U64 => size_of::(), - RocType::I128 => size_of::(), - RocType::U128 => size_of::(), - RocType::F32 => size_of::(), - RocType::F64 => size_of::(), - RocType::F128 => todo!(), - RocType::RocDec => size_of::(), + RocType::Num(num) => num.size(), RocType::RocStr | RocType::RocList(_) | RocType::RocDict(_, _) | RocType::RocSet(_) => { 3 * target_info.ptr_size() } @@ -395,7 +400,7 @@ impl RocType { | RocType::RocDict(_, _) | RocType::RocSet(_) | RocType::RocBox(_) => target_info.ptr_alignment_bytes(), - RocType::RocDec => align_of::(), + RocType::Num(num) => num.alignment(target_info), RocType::Bool => align_of::(), RocType::TagUnion(RocTagUnion::NonRecursive { tags, .. }) => { // The smallest alignment this could possibly have is based on the number of tags - e.g. @@ -446,19 +451,6 @@ impl RocType { RocType::Struct { fields, .. } => fields.iter().fold(0, |align, (_, field_id)| { align.max(types.get(*field_id).alignment(types, target_info)) }), - RocType::I8 => IntWidth::I8.alignment_bytes(target_info) as usize, - RocType::U8 => IntWidth::U8.alignment_bytes(target_info) as usize, - RocType::I16 => IntWidth::I16.alignment_bytes(target_info) as usize, - RocType::U16 => IntWidth::U16.alignment_bytes(target_info) as usize, - RocType::I32 => IntWidth::I32.alignment_bytes(target_info) as usize, - RocType::U32 => IntWidth::U32.alignment_bytes(target_info) as usize, - RocType::I64 => IntWidth::I64.alignment_bytes(target_info) as usize, - RocType::U64 => IntWidth::U64.alignment_bytes(target_info) as usize, - RocType::I128 => IntWidth::I128.alignment_bytes(target_info) as usize, - RocType::U128 => IntWidth::U128.alignment_bytes(target_info) as usize, - RocType::F32 => FloatWidth::F32.alignment_bytes(target_info) as usize, - RocType::F64 => FloatWidth::F64.alignment_bytes(target_info) as usize, - RocType::F128 => FloatWidth::F128.alignment_bytes(target_info) as usize, RocType::TransparentWrapper { content, .. } | RocType::TagUnion(RocTagUnion::NullableUnwrapped { non_null_payload: content,