mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
exit early from range checking
This commit is contained in:
parent
e3b6a38394
commit
b46721e43b
2 changed files with 80 additions and 37 deletions
|
@ -267,47 +267,53 @@ pub trait TypedNumericBound {
|
||||||
fn bounded_range(&self) -> Vec<Variable>;
|
fn bounded_range(&self) -> Vec<Variable>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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> {
|
fn bounded_range(&self) -> Vec<Variable> {
|
||||||
match self {
|
match self {
|
||||||
IntBound::None => vec![],
|
IntBound::None => vec![],
|
||||||
IntBound::Exact(w) => vec![match w {
|
IntBound::Exact(w) => vec![int_width_to_variable(*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,
|
|
||||||
}],
|
|
||||||
IntBound::AtLeast { sign, width } => {
|
IntBound::AtLeast { sign, width } => {
|
||||||
let whole_range: &[(IntWidth, Variable)] = match sign {
|
let whole_range: &[(IntWidth, Variable)] = match sign {
|
||||||
SignDemand::NoDemand => {
|
SignDemand::NoDemand => NO_DEMAND_INT_VARIABLES,
|
||||||
&[
|
SignDemand::Signed => SIGNED_INT_VARIABLES,
|
||||||
(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),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
SignDemand::Signed => &[
|
|
||||||
(IntWidth::I8, Variable::I8),
|
|
||||||
(IntWidth::I16, Variable::I16),
|
|
||||||
(IntWidth::I32, Variable::I32),
|
|
||||||
(IntWidth::I64, Variable::I64),
|
|
||||||
(IntWidth::I128, Variable::I128),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
whole_range
|
whole_range
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -454,9 +454,46 @@ fn check_valid_range(
|
||||||
range: VariableSubsSlice,
|
range: VariableSubsSlice,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
) -> Outcome {
|
) -> Outcome {
|
||||||
let slice = subs.get_subs_slice(range).to_vec();
|
let slice = subs.get_subs_slice(range);
|
||||||
|
let content = subs.get_content_without_compacting(var);
|
||||||
|
|
||||||
let mut it = slice.iter().peekable();
|
macro_rules! is_in_range {
|
||||||
|
($var:expr) => {
|
||||||
|
if slice.contains(&$var) {
|
||||||
|
return Outcome::default();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Content::Alias(symbol, _, _, _) = content {
|
||||||
|
match *symbol {
|
||||||
|
Symbol::NUM_I8 => is_in_range!(Variable::I8),
|
||||||
|
Symbol::NUM_U8 => is_in_range!(Variable::U8),
|
||||||
|
Symbol::NUM_I16 => is_in_range!(Variable::I16),
|
||||||
|
Symbol::NUM_U16 => is_in_range!(Variable::U16),
|
||||||
|
Symbol::NUM_I32 => is_in_range!(Variable::I32),
|
||||||
|
Symbol::NUM_U32 => is_in_range!(Variable::U32),
|
||||||
|
Symbol::NUM_I64 => is_in_range!(Variable::I64),
|
||||||
|
Symbol::NUM_NAT => is_in_range!(Variable::NAT),
|
||||||
|
Symbol::NUM_U64 => is_in_range!(Variable::U64),
|
||||||
|
Symbol::NUM_I128 => is_in_range!(Variable::I128),
|
||||||
|
Symbol::NUM_U128 => is_in_range!(Variable::U128),
|
||||||
|
|
||||||
|
Symbol::NUM_DEC => is_in_range!(Variable::DEC),
|
||||||
|
Symbol::NUM_F32 => is_in_range!(Variable::F32),
|
||||||
|
Symbol::NUM_F64 => is_in_range!(Variable::F64),
|
||||||
|
|
||||||
|
Symbol::NUM_NUM | Symbol::NUM_INT | Symbol::NUM_FRAC => {
|
||||||
|
// these satisfy any range that they are given
|
||||||
|
return Outcome::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let vec = slice.to_vec();
|
||||||
|
let mut it = vec.iter().peekable();
|
||||||
while let Some(&possible_var) = it.next() {
|
while let Some(&possible_var) = it.next() {
|
||||||
let snapshot = subs.snapshot();
|
let snapshot = subs.snapshot();
|
||||||
let old_pool = pool.clone();
|
let old_pool = pool.clone();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue