From d43bda83b4a0198ffb7c7f07ce5f3ff24a891aaa Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 21 May 2022 20:50:06 +0200 Subject: [PATCH] cleanup --- compiler/constrain/src/builtins.rs | 115 +++++------------------------ compiler/types/src/num.rs | 23 +++--- compiler/types/src/subs.rs | 2 +- compiler/types/src/types.rs | 4 +- compiler/unify/src/unify.rs | 6 +- 5 files changed, 37 insertions(+), 113 deletions(-) diff --git a/compiler/constrain/src/builtins.rs b/compiler/constrain/src/builtins.rs index 4725a41a16..17128e9de1 100644 --- a/compiler/constrain/src/builtins.rs +++ b/compiler/constrain/src/builtins.rs @@ -4,7 +4,7 @@ use roc_can::expected::Expected::{self, *}; use roc_can::num::{FloatBound, FloatWidth, IntBound, IntWidth, NumBound, SignDemand}; use roc_module::symbol::Symbol; use roc_region::all::Region; -use roc_types::num::NumericBound; +use roc_types::num::NumericRange; use roc_types::subs::Variable; use roc_types::types::Type::{self, *}; use roc_types::types::{AliasKind, Category}; @@ -23,6 +23,8 @@ pub fn add_numeric_bound_constr( let range = bound.numeric_bound(); let total_num_type = num_type; + use roc_types::num::{float_width_to_variable, int_width_to_variable}; + match range { NumericBound::None => { // no additional constraints @@ -48,10 +50,7 @@ pub fn add_numeric_bound_constr( total_num_type } - NumericBound::IntAtLeastSigned(_) - | NumericBound::IntAtLeastEitherSign(_) - | NumericBound::NumAtLeastSigned(_) - | NumericBound::NumAtLeastEitherSign(_) => RangedNumber(Box::new(total_num_type), range), + NumericBound::Range(range) => RangedNumber(Box::new(total_num_type), range), } } @@ -280,68 +279,10 @@ pub fn num_num(typ: Type) -> Type { } pub trait TypedNumericBound { - fn bounded_range(&self) -> Vec; - fn numeric_bound(&self) -> NumericBound; } -const fn int_width_to_variable(w: IntWidth) -> Variable { - match w { - IntWidth::U8 => Variable::U8, - IntWidth::U16 => Variable::U16, - IntWidth::U32 => Variable::U32, - IntWidth::U64 => Variable::U64, - IntWidth::U128 => Variable::U128, - IntWidth::I8 => Variable::I8, - IntWidth::I16 => Variable::I16, - IntWidth::I32 => Variable::I32, - IntWidth::I64 => Variable::I64, - IntWidth::I128 => Variable::I128, - IntWidth::Nat => Variable::NAT, - } -} - -const NO_DEMAND_INT_VARIABLES: &[(IntWidth, Variable)] = &[ - (IntWidth::I8, Variable::I8), - (IntWidth::U8, Variable::U8), - (IntWidth::I16, Variable::I16), - (IntWidth::U16, Variable::U16), - (IntWidth::I32, Variable::I32), - (IntWidth::U32, Variable::U32), - (IntWidth::I64, Variable::I64), - (IntWidth::Nat, Variable::NAT), // FIXME: Nat's order here depends on the platform! - (IntWidth::U64, Variable::U64), - (IntWidth::I128, Variable::I128), - (IntWidth::U128, Variable::U128), -]; - -const SIGNED_INT_VARIABLES: &[(IntWidth, Variable)] = &[ - (IntWidth::I8, Variable::I8), - (IntWidth::I16, Variable::I16), - (IntWidth::I32, Variable::I32), - (IntWidth::I64, Variable::I64), - (IntWidth::I128, Variable::I128), -]; - impl TypedNumericBound for IntBound { - fn bounded_range(&self) -> Vec { - match self { - IntBound::None => vec![], - IntBound::Exact(w) => vec![int_width_to_variable(*w)], - IntBound::AtLeast { sign, width } => { - let whole_range: &[(IntWidth, Variable)] = match sign { - SignDemand::NoDemand => NO_DEMAND_INT_VARIABLES, - SignDemand::Signed => SIGNED_INT_VARIABLES, - }; - whole_range - .iter() - .skip_while(|(lower_bound, _)| *lower_bound != *width) - .map(|(_, var)| *var) - .collect() - } - } - } - fn numeric_bound(&self) -> NumericBound { match self { IntBound::None => NumericBound::None, @@ -349,35 +290,16 @@ impl TypedNumericBound for IntBound { IntBound::AtLeast { sign: SignDemand::NoDemand, width, - } => NumericBound::IntAtLeastEitherSign(*width), + } => NumericBound::Range(NumericRange::IntAtLeastEitherSign(*width)), IntBound::AtLeast { sign: SignDemand::Signed, width, - } => NumericBound::IntAtLeastSigned(*width), + } => NumericBound::Range(NumericRange::IntAtLeastSigned(*width)), } } } -const fn float_width_to_variable(w: FloatWidth) -> Variable { - match w { - FloatWidth::Dec => Variable::DEC, - FloatWidth::F32 => Variable::F32, - FloatWidth::F64 => Variable::F64, - } -} - impl TypedNumericBound for FloatBound { - fn bounded_range(&self) -> Vec { - match self { - FloatBound::None => vec![], - FloatBound::Exact(w) => vec![match w { - FloatWidth::Dec => Variable::DEC, - FloatWidth::F32 => Variable::F32, - FloatWidth::F64 => Variable::F64, - }], - } - } - fn numeric_bound(&self) -> NumericBound { match self { FloatBound::None => NumericBound::None, @@ -387,28 +309,27 @@ impl TypedNumericBound for FloatBound { } impl TypedNumericBound for NumBound { - fn bounded_range(&self) -> Vec { - match self { - NumBound::None => vec![], - &NumBound::AtLeastIntOrFloat { sign, width } => { - let mut range = IntBound::AtLeast { sign, width }.bounded_range(); - range.extend_from_slice(&[Variable::F32, Variable::F64, Variable::DEC]); - range - } - } - } - fn numeric_bound(&self) -> NumericBound { match self { NumBound::None => NumericBound::None, &NumBound::AtLeastIntOrFloat { sign: SignDemand::NoDemand, width, - } => NumericBound::NumAtLeastEitherSign(width), + } => NumericBound::Range(NumericRange::NumAtLeastEitherSign(width)), &NumBound::AtLeastIntOrFloat { sign: SignDemand::Signed, width, - } => NumericBound::NumAtLeastSigned(width), + } => NumericBound::Range(NumericRange::NumAtLeastSigned(width)), } } } + +/// A bound placed on a number because of its literal value. +/// e.g. `-5` cannot be unsigned, and 300 does not fit in a U8 +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum NumericBound { + None, + FloatExact(FloatWidth), + IntExact(IntWidth), + Range(NumericRange), +} diff --git a/compiler/types/src/num.rs b/compiler/types/src/num.rs index c988f99c5a..39ef083153 100644 --- a/compiler/types/src/num.rs +++ b/compiler/types/src/num.rs @@ -4,17 +4,14 @@ use roc_module::symbol::Symbol; /// A bound placed on a number because of its literal value. /// e.g. `-5` cannot be unsigned, and 300 does not fit in a U8 #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum NumericBound { - None, - FloatExact(FloatWidth), - IntExact(IntWidth), +pub enum NumericRange { IntAtLeastSigned(IntWidth), IntAtLeastEitherSign(IntWidth), NumAtLeastSigned(IntWidth), NumAtLeastEitherSign(IntWidth), } -impl NumericBound { +impl NumericRange { pub fn contains_symbol(&self, symbol: Symbol) -> bool { match symbol { Symbol::NUM_I8 => self.contains_int_width(IntWidth::I8), @@ -47,14 +44,13 @@ impl NumericBound { } fn contains_int_width(&self, width: IntWidth) -> bool { - use NumericBound::*; + use NumericRange::*; let (range_sign, at_least_width) = match self { IntAtLeastSigned(width) => (SignDemand::Signed, width), IntAtLeastEitherSign(width) => (SignDemand::NoDemand, width), NumAtLeastSigned(width) => (SignDemand::Signed, width), NumAtLeastEitherSign(width) => (SignDemand::NoDemand, width), - _ => panic!(), }; let (actual_sign, _) = width.sign_and_width(); @@ -67,7 +63,7 @@ impl NumericBound { } pub fn variable_slice(&self) -> &'static [Variable] { - use NumericBound::*; + use NumericRange::*; match self { IntAtLeastSigned(width) => { @@ -96,7 +92,6 @@ impl NumericBound { &ALL_VARIABLES[start..] } - _ => panic!(), } } } @@ -267,7 +262,7 @@ pub enum NumBound { }, } -const fn int_width_to_variable(w: IntWidth) -> Variable { +pub const fn int_width_to_variable(w: IntWidth) -> Variable { match w { IntWidth::U8 => Variable::U8, IntWidth::U16 => Variable::U16, @@ -283,6 +278,14 @@ const fn int_width_to_variable(w: IntWidth) -> Variable { } } +pub const fn float_width_to_variable(w: FloatWidth) -> Variable { + match w { + FloatWidth::Dec => Variable::DEC, + FloatWidth::F32 => Variable::F32, + FloatWidth::F64 => Variable::F64, + } +} + const ALL_VARIABLES: &[Variable] = &[ Variable::I8, Variable::U8, diff --git a/compiler/types/src/subs.rs b/compiler/types/src/subs.rs index ef8a0727d8..5baee3d4fc 100644 --- a/compiler/types/src/subs.rs +++ b/compiler/types/src/subs.rs @@ -2008,7 +2008,7 @@ pub enum Content { }, Structure(FlatType), Alias(Symbol, AliasVariables, Variable, AliasKind), - RangedNumber(Variable, crate::num::NumericBound), + RangedNumber(Variable, crate::num::NumericRange), Error, } diff --git a/compiler/types/src/types.rs b/compiler/types/src/types.rs index dc43f0ea90..fcb0631b2a 100644 --- a/compiler/types/src/types.rs +++ b/compiler/types/src/types.rs @@ -1,4 +1,4 @@ -use crate::num::NumericBound; +use crate::num::NumericRange; use crate::pretty_print::Parens; use crate::subs::{ GetSubsSlice, RecordFields, Subs, UnionTags, VarStore, Variable, VariableSubsSlice, @@ -255,7 +255,7 @@ pub enum Type { /// Applying a type to some arguments (e.g. Dict.Dict String Int) Apply(Symbol, Vec, Region), Variable(Variable), - RangedNumber(Box, NumericBound), + RangedNumber(Box, NumericRange), /// A type error, which will code gen to a runtime error Erroneous(Problem), } diff --git a/compiler/unify/src/unify.rs b/compiler/unify/src/unify.rs index 089e9ca4ca..180e767e01 100644 --- a/compiler/unify/src/unify.rs +++ b/compiler/unify/src/unify.rs @@ -5,7 +5,7 @@ use roc_debug_flags::{ROC_PRINT_MISMATCHES, ROC_PRINT_UNIFICATIONS}; use roc_error_macros::internal_error; use roc_module::ident::{Lowercase, TagName}; use roc_module::symbol::Symbol; -use roc_types::num::NumericBound; +use roc_types::num::NumericRange; use roc_types::subs::Content::{self, *}; use roc_types::subs::{ AliasVariables, Descriptor, ErrorTypeContext, FlatType, GetSubsSlice, Mark, OptVariable, @@ -414,7 +414,7 @@ fn unify_ranged_number( pool: &mut Pool, ctx: &Context, real_var: Variable, - range_vars: NumericBound, + range_vars: NumericRange, ) -> Outcome { let other_content = &ctx.second_desc.content; @@ -448,7 +448,7 @@ fn unify_ranged_number( check_valid_range(subs, ctx.second, range_vars) } -fn check_valid_range(subs: &mut Subs, var: Variable, range: NumericBound) -> Outcome { +fn check_valid_range(subs: &mut Subs, var: Variable, range: NumericRange) -> Outcome { let content = subs.get_content_without_compacting(var); match content {