mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
remove the snapshots
This commit is contained in:
parent
cb40aab21f
commit
98ce9f4d09
9 changed files with 271 additions and 164 deletions
|
@ -1,3 +1,106 @@
|
|||
use crate::subs::Variable;
|
||||
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),
|
||||
IntAtLeastSigned(IntWidth),
|
||||
IntAtLeastEitherSign(IntWidth),
|
||||
NumAtLeastSigned(IntWidth),
|
||||
NumAtLeastEitherSign(IntWidth),
|
||||
}
|
||||
|
||||
impl NumericBound {
|
||||
pub fn contains_symbol(&self, symbol: Symbol) -> bool {
|
||||
match symbol {
|
||||
Symbol::NUM_I8 => self.contains_int_width(IntWidth::I8),
|
||||
Symbol::NUM_U8 => self.contains_int_width(IntWidth::U8),
|
||||
Symbol::NUM_I16 => self.contains_int_width(IntWidth::I16),
|
||||
Symbol::NUM_U16 => self.contains_int_width(IntWidth::U16),
|
||||
Symbol::NUM_I32 => self.contains_int_width(IntWidth::I32),
|
||||
Symbol::NUM_U32 => self.contains_int_width(IntWidth::U32),
|
||||
Symbol::NUM_I64 => self.contains_int_width(IntWidth::I64),
|
||||
Symbol::NUM_NAT => self.contains_int_width(IntWidth::Nat),
|
||||
Symbol::NUM_U64 => self.contains_int_width(IntWidth::U64),
|
||||
Symbol::NUM_I128 => self.contains_int_width(IntWidth::I128),
|
||||
Symbol::NUM_U128 => self.contains_int_width(IntWidth::U128),
|
||||
|
||||
Symbol::NUM_DEC => self.contains_float_width(FloatWidth::Dec),
|
||||
Symbol::NUM_F32 => self.contains_float_width(FloatWidth::F32),
|
||||
Symbol::NUM_F64 => self.contains_float_width(FloatWidth::F64),
|
||||
|
||||
Symbol::NUM_NUM | Symbol::NUM_INT | Symbol::NUM_FRAC => {
|
||||
// these satisfy any range that they are given
|
||||
true
|
||||
}
|
||||
|
||||
_ => unreachable!("weird number symbol {:?}", symbol),
|
||||
}
|
||||
}
|
||||
|
||||
fn contains_float_width(&self, _width: FloatWidth) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn contains_int_width(&self, width: IntWidth) -> bool {
|
||||
use NumericBound::*;
|
||||
|
||||
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();
|
||||
|
||||
if let (IntSign::Unsigned, SignDemand::Signed) = (actual_sign, range_sign) {
|
||||
return false;
|
||||
}
|
||||
|
||||
width.sign_and_width().1 >= at_least_width.sign_and_width().1
|
||||
}
|
||||
|
||||
pub fn variable_slice(&self) -> &'static [Variable] {
|
||||
use NumericBound::*;
|
||||
|
||||
match self {
|
||||
IntAtLeastSigned(width) => {
|
||||
let target = int_width_to_variable(*width);
|
||||
let start = SIGNED_VARIABLES.iter().position(|v| *v == target).unwrap();
|
||||
let end = SIGNED_VARIABLES.len() - 3;
|
||||
|
||||
&SIGNED_VARIABLES[start..end]
|
||||
}
|
||||
IntAtLeastEitherSign(width) => {
|
||||
let target = int_width_to_variable(*width);
|
||||
let start = ALL_VARIABLES.iter().position(|v| *v == target).unwrap();
|
||||
let end = ALL_VARIABLES.len() - 3;
|
||||
|
||||
&ALL_VARIABLES[start..end]
|
||||
}
|
||||
NumAtLeastSigned(width) => {
|
||||
let target = int_width_to_variable(*width);
|
||||
let start = SIGNED_VARIABLES.iter().position(|v| *v == target).unwrap();
|
||||
|
||||
&SIGNED_VARIABLES[start..]
|
||||
}
|
||||
NumAtLeastEitherSign(width) => {
|
||||
let target = int_width_to_variable(*width);
|
||||
let start = ALL_VARIABLES.iter().position(|v| *v == target).unwrap();
|
||||
|
||||
&ALL_VARIABLES[start..]
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum IntSign {
|
||||
Unsigned,
|
||||
|
@ -163,3 +266,47 @@ pub enum NumBound {
|
|||
width: IntWidth,
|
||||
},
|
||||
}
|
||||
|
||||
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 ALL_VARIABLES: &[Variable] = &[
|
||||
Variable::I8,
|
||||
Variable::U8,
|
||||
Variable::I16,
|
||||
Variable::U16,
|
||||
Variable::I32,
|
||||
Variable::U32,
|
||||
Variable::I64,
|
||||
Variable::NAT, // FIXME: Nat's order here depends on the platfor,
|
||||
Variable::U64,
|
||||
Variable::I128,
|
||||
Variable::U128,
|
||||
Variable::F32,
|
||||
Variable::F64,
|
||||
Variable::DEC,
|
||||
];
|
||||
|
||||
const SIGNED_VARIABLES: &[Variable] = &[
|
||||
Variable::I8,
|
||||
Variable::I16,
|
||||
Variable::I32,
|
||||
Variable::I64,
|
||||
Variable::I128,
|
||||
Variable::F32,
|
||||
Variable::F64,
|
||||
Variable::DEC,
|
||||
];
|
||||
|
|
|
@ -220,12 +220,8 @@ fn find_names_needed(
|
|||
// TODO should we also look in the actual variable?
|
||||
// find_names_needed(_actual, subs, roots, root_appearances, names_taken);
|
||||
}
|
||||
&RangedNumber(typ, vars) => {
|
||||
&RangedNumber(typ, _) => {
|
||||
find_names_needed(typ, subs, roots, root_appearances, names_taken);
|
||||
for var_index in vars {
|
||||
let var = subs[var_index];
|
||||
find_names_needed(var, subs, roots, root_appearances, names_taken);
|
||||
}
|
||||
}
|
||||
Error | Structure(Erroneous(_)) | Structure(EmptyRecord) | Structure(EmptyTagUnion) => {
|
||||
// Errors and empty records don't need names.
|
||||
|
|
|
@ -713,8 +713,7 @@ fn subs_fmt_content(this: &Content, subs: &Subs, f: &mut fmt::Formatter) -> fmt:
|
|||
)
|
||||
}
|
||||
Content::RangedNumber(typ, range) => {
|
||||
let slice = subs.get_subs_slice(*range);
|
||||
write!(f, "RangedNumber({:?}, {:?})", typ, slice)
|
||||
write!(f, "RangedNumber({:?}, {:?})", typ, range)
|
||||
}
|
||||
Content::Error => write!(f, "Error"),
|
||||
}
|
||||
|
@ -2009,7 +2008,7 @@ pub enum Content {
|
|||
},
|
||||
Structure(FlatType),
|
||||
Alias(Symbol, AliasVariables, Variable, AliasKind),
|
||||
RangedNumber(Variable, VariableSubsSlice),
|
||||
RangedNumber(Variable, crate::num::NumericBound),
|
||||
Error,
|
||||
}
|
||||
|
||||
|
@ -3025,16 +3024,10 @@ fn explicit_substitute(
|
|||
|
||||
in_var
|
||||
}
|
||||
RangedNumber(typ, vars) => {
|
||||
for index in vars.into_iter() {
|
||||
let var = subs[index];
|
||||
let new_var = explicit_substitute(subs, from, to, var, seen);
|
||||
subs[index] = new_var;
|
||||
}
|
||||
|
||||
RangedNumber(typ, range) => {
|
||||
let new_typ = explicit_substitute(subs, from, to, typ, seen);
|
||||
|
||||
subs.set_content(in_var, RangedNumber(new_typ, vars));
|
||||
subs.set_content(in_var, RangedNumber(new_typ, range));
|
||||
|
||||
in_var
|
||||
}
|
||||
|
@ -3094,12 +3087,7 @@ fn get_var_names(
|
|||
get_var_names(subs, subs[arg_var], answer)
|
||||
}),
|
||||
|
||||
RangedNumber(typ, vars) => {
|
||||
let taken_names = get_var_names(subs, typ, taken_names);
|
||||
vars.into_iter().fold(taken_names, |answer, var| {
|
||||
get_var_names(subs, subs[var], answer)
|
||||
})
|
||||
}
|
||||
RangedNumber(typ, _) => get_var_names(subs, typ, taken_names),
|
||||
|
||||
Structure(flat_type) => match flat_type {
|
||||
FlatType::Apply(_, args) => {
|
||||
|
@ -3340,12 +3328,12 @@ fn content_to_err_type(
|
|||
RangedNumber(typ, range) => {
|
||||
let err_type = var_to_err_type(subs, state, typ);
|
||||
|
||||
if state.context == ErrorTypeContext::ExpandRanges {
|
||||
let mut types = Vec::with_capacity(range.len());
|
||||
for var_index in range {
|
||||
let var = subs[var_index];
|
||||
dbg!(range);
|
||||
|
||||
types.push(var_to_err_type(subs, state, var));
|
||||
if state.context == ErrorTypeContext::ExpandRanges {
|
||||
let mut types = Vec::new();
|
||||
for var in range.variable_slice() {
|
||||
types.push(var_to_err_type(subs, state, *var));
|
||||
}
|
||||
ErrorType::Range(Box::new(err_type), types)
|
||||
} else {
|
||||
|
@ -3645,9 +3633,8 @@ fn restore_help(subs: &mut Subs, initial: Variable) {
|
|||
stack.push(*var);
|
||||
}
|
||||
|
||||
RangedNumber(typ, vars) => {
|
||||
RangedNumber(typ, _vars) => {
|
||||
stack.push(*typ);
|
||||
stack.extend(var_slice(*vars));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3833,10 +3820,7 @@ impl StorageSubs {
|
|||
Self::offset_variable(offsets, *actual),
|
||||
*kind,
|
||||
),
|
||||
RangedNumber(typ, vars) => RangedNumber(
|
||||
Self::offset_variable(offsets, *typ),
|
||||
Self::offset_variable_slice(offsets, *vars),
|
||||
),
|
||||
RangedNumber(typ, range) => RangedNumber(Self::offset_variable(offsets, *typ), *range),
|
||||
Error => Content::Error,
|
||||
}
|
||||
}
|
||||
|
@ -4262,18 +4246,10 @@ fn deep_copy_var_to_help(env: &mut DeepCopyVarToEnv<'_>, var: Variable) -> Varia
|
|||
copy
|
||||
}
|
||||
|
||||
RangedNumber(typ, vars) => {
|
||||
RangedNumber(typ, range) => {
|
||||
let new_typ = deep_copy_var_to_help(env, typ);
|
||||
|
||||
let new_vars = SubsSlice::reserve_into_subs(env.target, vars.len());
|
||||
|
||||
for (target_index, var_index) in (new_vars.indices()).zip(vars) {
|
||||
let var = env.source[var_index];
|
||||
let copy_var = deep_copy_var_to_help(env, var);
|
||||
env.target.variables[target_index] = copy_var;
|
||||
}
|
||||
|
||||
let new_content = RangedNumber(new_typ, new_vars);
|
||||
let new_content = RangedNumber(new_typ, range);
|
||||
|
||||
env.target.set(copy, make_descriptor(new_content));
|
||||
copy
|
||||
|
@ -4731,18 +4707,10 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
|
|||
copy
|
||||
}
|
||||
|
||||
RangedNumber(typ, vars) => {
|
||||
RangedNumber(typ, range) => {
|
||||
let new_typ = copy_import_to_help(env, max_rank, typ);
|
||||
|
||||
let new_vars = SubsSlice::reserve_into_subs(env.target, vars.len());
|
||||
|
||||
for (target_index, var_index) in (new_vars.indices()).zip(vars) {
|
||||
let var = env.source[var_index];
|
||||
let copy_var = copy_import_to_help(env, max_rank, var);
|
||||
env.target.variables[target_index] = copy_var;
|
||||
}
|
||||
|
||||
let new_content = RangedNumber(new_typ, new_vars);
|
||||
let new_content = RangedNumber(new_typ, range);
|
||||
|
||||
env.target.set(copy, make_descriptor(new_content));
|
||||
copy
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::num::NumericBound;
|
||||
use crate::pretty_print::Parens;
|
||||
use crate::subs::{
|
||||
GetSubsSlice, RecordFields, Subs, UnionTags, VarStore, Variable, VariableSubsSlice,
|
||||
|
@ -254,7 +255,7 @@ pub enum Type {
|
|||
/// Applying a type to some arguments (e.g. Dict.Dict String Int)
|
||||
Apply(Symbol, Vec<Type>, Region),
|
||||
Variable(Variable),
|
||||
RangedNumber(Box<Type>, Vec<Variable>),
|
||||
RangedNumber(Box<Type>, NumericBound),
|
||||
/// A type error, which will code gen to a runtime error
|
||||
Erroneous(Problem),
|
||||
}
|
||||
|
@ -324,7 +325,7 @@ impl Clone for Type {
|
|||
}
|
||||
Self::Apply(arg0, arg1, arg2) => Self::Apply(*arg0, arg1.clone(), *arg2),
|
||||
Self::Variable(arg0) => Self::Variable(*arg0),
|
||||
Self::RangedNumber(arg0, arg1) => Self::RangedNumber(arg0.clone(), arg1.clone()),
|
||||
Self::RangedNumber(arg0, arg1) => Self::RangedNumber(arg0.clone(), *arg1),
|
||||
Self::Erroneous(arg0) => Self::Erroneous(arg0.clone()),
|
||||
}
|
||||
}
|
||||
|
@ -1089,9 +1090,7 @@ impl Type {
|
|||
} => actual_type.contains_variable(rep_variable),
|
||||
HostExposedAlias { actual, .. } => actual.contains_variable(rep_variable),
|
||||
Apply(_, args, _) => args.iter().any(|arg| arg.contains_variable(rep_variable)),
|
||||
RangedNumber(typ, vars) => {
|
||||
typ.contains_variable(rep_variable) || vars.iter().any(|&v| v == rep_variable)
|
||||
}
|
||||
RangedNumber(typ, _) => typ.contains_variable(rep_variable),
|
||||
EmptyRec | EmptyTagUnion | Erroneous(_) => false,
|
||||
}
|
||||
}
|
||||
|
@ -1594,9 +1593,8 @@ fn variables_help(tipe: &Type, accum: &mut ImSet<Variable>) {
|
|||
}
|
||||
variables_help(actual, accum);
|
||||
}
|
||||
RangedNumber(typ, vars) => {
|
||||
RangedNumber(typ, _) => {
|
||||
variables_help(typ, accum);
|
||||
accum.extend(vars.iter().copied());
|
||||
}
|
||||
Apply(_, args, _) => {
|
||||
for x in args {
|
||||
|
@ -1730,9 +1728,8 @@ fn variables_help_detailed(tipe: &Type, accum: &mut VariableDetail) {
|
|||
}
|
||||
variables_help_detailed(actual, accum);
|
||||
}
|
||||
RangedNumber(typ, vars) => {
|
||||
RangedNumber(typ, _) => {
|
||||
variables_help_detailed(typ, accum);
|
||||
accum.type_variables.extend(vars);
|
||||
}
|
||||
Apply(_, args, _) => {
|
||||
for x in args {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue