mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
cleanup
This commit is contained in:
parent
98ce9f4d09
commit
d43bda83b4
5 changed files with 37 additions and 113 deletions
|
@ -4,7 +4,7 @@ use roc_can::expected::Expected::{self, *};
|
||||||
use roc_can::num::{FloatBound, FloatWidth, IntBound, IntWidth, NumBound, SignDemand};
|
use roc_can::num::{FloatBound, FloatWidth, IntBound, IntWidth, NumBound, SignDemand};
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_region::all::Region;
|
use roc_region::all::Region;
|
||||||
use roc_types::num::NumericBound;
|
use roc_types::num::NumericRange;
|
||||||
use roc_types::subs::Variable;
|
use roc_types::subs::Variable;
|
||||||
use roc_types::types::Type::{self, *};
|
use roc_types::types::Type::{self, *};
|
||||||
use roc_types::types::{AliasKind, Category};
|
use roc_types::types::{AliasKind, Category};
|
||||||
|
@ -23,6 +23,8 @@ pub fn add_numeric_bound_constr(
|
||||||
let range = bound.numeric_bound();
|
let range = bound.numeric_bound();
|
||||||
let total_num_type = num_type;
|
let total_num_type = num_type;
|
||||||
|
|
||||||
|
use roc_types::num::{float_width_to_variable, int_width_to_variable};
|
||||||
|
|
||||||
match range {
|
match range {
|
||||||
NumericBound::None => {
|
NumericBound::None => {
|
||||||
// no additional constraints
|
// no additional constraints
|
||||||
|
@ -48,10 +50,7 @@ pub fn add_numeric_bound_constr(
|
||||||
|
|
||||||
total_num_type
|
total_num_type
|
||||||
}
|
}
|
||||||
NumericBound::IntAtLeastSigned(_)
|
NumericBound::Range(range) => RangedNumber(Box::new(total_num_type), range),
|
||||||
| NumericBound::IntAtLeastEitherSign(_)
|
|
||||||
| NumericBound::NumAtLeastSigned(_)
|
|
||||||
| NumericBound::NumAtLeastEitherSign(_) => RangedNumber(Box::new(total_num_type), range),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,68 +279,10 @@ pub fn num_num(typ: Type) -> Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TypedNumericBound {
|
pub trait TypedNumericBound {
|
||||||
fn bounded_range(&self) -> Vec<Variable>;
|
|
||||||
|
|
||||||
fn numeric_bound(&self) -> NumericBound;
|
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 {
|
impl TypedNumericBound for IntBound {
|
||||||
fn bounded_range(&self) -> Vec<Variable> {
|
|
||||||
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 {
|
fn numeric_bound(&self) -> NumericBound {
|
||||||
match self {
|
match self {
|
||||||
IntBound::None => NumericBound::None,
|
IntBound::None => NumericBound::None,
|
||||||
|
@ -349,35 +290,16 @@ impl TypedNumericBound for IntBound {
|
||||||
IntBound::AtLeast {
|
IntBound::AtLeast {
|
||||||
sign: SignDemand::NoDemand,
|
sign: SignDemand::NoDemand,
|
||||||
width,
|
width,
|
||||||
} => NumericBound::IntAtLeastEitherSign(*width),
|
} => NumericBound::Range(NumericRange::IntAtLeastEitherSign(*width)),
|
||||||
IntBound::AtLeast {
|
IntBound::AtLeast {
|
||||||
sign: SignDemand::Signed,
|
sign: SignDemand::Signed,
|
||||||
width,
|
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 {
|
impl TypedNumericBound for FloatBound {
|
||||||
fn bounded_range(&self) -> Vec<Variable> {
|
|
||||||
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 {
|
fn numeric_bound(&self) -> NumericBound {
|
||||||
match self {
|
match self {
|
||||||
FloatBound::None => NumericBound::None,
|
FloatBound::None => NumericBound::None,
|
||||||
|
@ -387,28 +309,27 @@ impl TypedNumericBound for FloatBound {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypedNumericBound for NumBound {
|
impl TypedNumericBound for NumBound {
|
||||||
fn bounded_range(&self) -> Vec<Variable> {
|
|
||||||
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 {
|
fn numeric_bound(&self) -> NumericBound {
|
||||||
match self {
|
match self {
|
||||||
NumBound::None => NumericBound::None,
|
NumBound::None => NumericBound::None,
|
||||||
&NumBound::AtLeastIntOrFloat {
|
&NumBound::AtLeastIntOrFloat {
|
||||||
sign: SignDemand::NoDemand,
|
sign: SignDemand::NoDemand,
|
||||||
width,
|
width,
|
||||||
} => NumericBound::NumAtLeastEitherSign(width),
|
} => NumericBound::Range(NumericRange::NumAtLeastEitherSign(width)),
|
||||||
&NumBound::AtLeastIntOrFloat {
|
&NumBound::AtLeastIntOrFloat {
|
||||||
sign: SignDemand::Signed,
|
sign: SignDemand::Signed,
|
||||||
width,
|
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),
|
||||||
|
}
|
||||||
|
|
|
@ -4,17 +4,14 @@ use roc_module::symbol::Symbol;
|
||||||
/// A bound placed on a number because of its literal value.
|
/// 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
|
/// e.g. `-5` cannot be unsigned, and 300 does not fit in a U8
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum NumericBound {
|
pub enum NumericRange {
|
||||||
None,
|
|
||||||
FloatExact(FloatWidth),
|
|
||||||
IntExact(IntWidth),
|
|
||||||
IntAtLeastSigned(IntWidth),
|
IntAtLeastSigned(IntWidth),
|
||||||
IntAtLeastEitherSign(IntWidth),
|
IntAtLeastEitherSign(IntWidth),
|
||||||
NumAtLeastSigned(IntWidth),
|
NumAtLeastSigned(IntWidth),
|
||||||
NumAtLeastEitherSign(IntWidth),
|
NumAtLeastEitherSign(IntWidth),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NumericBound {
|
impl NumericRange {
|
||||||
pub fn contains_symbol(&self, symbol: Symbol) -> bool {
|
pub fn contains_symbol(&self, symbol: Symbol) -> bool {
|
||||||
match symbol {
|
match symbol {
|
||||||
Symbol::NUM_I8 => self.contains_int_width(IntWidth::I8),
|
Symbol::NUM_I8 => self.contains_int_width(IntWidth::I8),
|
||||||
|
@ -47,14 +44,13 @@ impl NumericBound {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contains_int_width(&self, width: IntWidth) -> bool {
|
fn contains_int_width(&self, width: IntWidth) -> bool {
|
||||||
use NumericBound::*;
|
use NumericRange::*;
|
||||||
|
|
||||||
let (range_sign, at_least_width) = match self {
|
let (range_sign, at_least_width) = match self {
|
||||||
IntAtLeastSigned(width) => (SignDemand::Signed, width),
|
IntAtLeastSigned(width) => (SignDemand::Signed, width),
|
||||||
IntAtLeastEitherSign(width) => (SignDemand::NoDemand, width),
|
IntAtLeastEitherSign(width) => (SignDemand::NoDemand, width),
|
||||||
NumAtLeastSigned(width) => (SignDemand::Signed, width),
|
NumAtLeastSigned(width) => (SignDemand::Signed, width),
|
||||||
NumAtLeastEitherSign(width) => (SignDemand::NoDemand, width),
|
NumAtLeastEitherSign(width) => (SignDemand::NoDemand, width),
|
||||||
_ => panic!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (actual_sign, _) = width.sign_and_width();
|
let (actual_sign, _) = width.sign_and_width();
|
||||||
|
@ -67,7 +63,7 @@ impl NumericBound {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variable_slice(&self) -> &'static [Variable] {
|
pub fn variable_slice(&self) -> &'static [Variable] {
|
||||||
use NumericBound::*;
|
use NumericRange::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
IntAtLeastSigned(width) => {
|
IntAtLeastSigned(width) => {
|
||||||
|
@ -96,7 +92,6 @@ impl NumericBound {
|
||||||
|
|
||||||
&ALL_VARIABLES[start..]
|
&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 {
|
match w {
|
||||||
IntWidth::U8 => Variable::U8,
|
IntWidth::U8 => Variable::U8,
|
||||||
IntWidth::U16 => Variable::U16,
|
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] = &[
|
const ALL_VARIABLES: &[Variable] = &[
|
||||||
Variable::I8,
|
Variable::I8,
|
||||||
Variable::U8,
|
Variable::U8,
|
||||||
|
|
|
@ -2008,7 +2008,7 @@ pub enum Content {
|
||||||
},
|
},
|
||||||
Structure(FlatType),
|
Structure(FlatType),
|
||||||
Alias(Symbol, AliasVariables, Variable, AliasKind),
|
Alias(Symbol, AliasVariables, Variable, AliasKind),
|
||||||
RangedNumber(Variable, crate::num::NumericBound),
|
RangedNumber(Variable, crate::num::NumericRange),
|
||||||
Error,
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::num::NumericBound;
|
use crate::num::NumericRange;
|
||||||
use crate::pretty_print::Parens;
|
use crate::pretty_print::Parens;
|
||||||
use crate::subs::{
|
use crate::subs::{
|
||||||
GetSubsSlice, RecordFields, Subs, UnionTags, VarStore, Variable, VariableSubsSlice,
|
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)
|
/// Applying a type to some arguments (e.g. Dict.Dict String Int)
|
||||||
Apply(Symbol, Vec<Type>, Region),
|
Apply(Symbol, Vec<Type>, Region),
|
||||||
Variable(Variable),
|
Variable(Variable),
|
||||||
RangedNumber(Box<Type>, NumericBound),
|
RangedNumber(Box<Type>, NumericRange),
|
||||||
/// A type error, which will code gen to a runtime error
|
/// A type error, which will code gen to a runtime error
|
||||||
Erroneous(Problem),
|
Erroneous(Problem),
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use roc_debug_flags::{ROC_PRINT_MISMATCHES, ROC_PRINT_UNIFICATIONS};
|
||||||
use roc_error_macros::internal_error;
|
use roc_error_macros::internal_error;
|
||||||
use roc_module::ident::{Lowercase, TagName};
|
use roc_module::ident::{Lowercase, TagName};
|
||||||
use roc_module::symbol::Symbol;
|
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::Content::{self, *};
|
||||||
use roc_types::subs::{
|
use roc_types::subs::{
|
||||||
AliasVariables, Descriptor, ErrorTypeContext, FlatType, GetSubsSlice, Mark, OptVariable,
|
AliasVariables, Descriptor, ErrorTypeContext, FlatType, GetSubsSlice, Mark, OptVariable,
|
||||||
|
@ -414,7 +414,7 @@ fn unify_ranged_number(
|
||||||
pool: &mut Pool,
|
pool: &mut Pool,
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
real_var: Variable,
|
real_var: Variable,
|
||||||
range_vars: NumericBound,
|
range_vars: NumericRange,
|
||||||
) -> Outcome {
|
) -> Outcome {
|
||||||
let other_content = &ctx.second_desc.content;
|
let other_content = &ctx.second_desc.content;
|
||||||
|
|
||||||
|
@ -448,7 +448,7 @@ fn unify_ranged_number(
|
||||||
check_valid_range(subs, ctx.second, range_vars)
|
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);
|
let content = subs.get_content_without_compacting(var);
|
||||||
|
|
||||||
match content {
|
match content {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue