mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-22 20:45:11 +00:00
Implement our own small-integer optimization (#7584)
## Summary This is a follow-up to #7469 that attempts to achieve similar gains, but without introducing malachite. Instead, this PR removes the `BigInt` type altogether, instead opting for a simple enum that allows us to store small integers directly and only allocate for values greater than `i64`: ```rust /// A Python integer literal. Represents both small (fits in an `i64`) and large integers. #[derive(Clone, PartialEq, Eq, Hash)] pub struct Int(Number); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Number { /// A "small" number that can be represented as an `i64`. Small(i64), /// A "large" number that cannot be represented as an `i64`. Big(Box<str>), } impl std::fmt::Display for Number { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Number::Small(value) => write!(f, "{value}"), Number::Big(value) => write!(f, "{value}"), } } } ``` We typically don't care about numbers greater than `isize` -- our only uses are comparisons against small constants (like `1`, `2`, `3`, etc.), so there's no real loss of information, except in one or two rules where we're now a little more conservative (with the worst-case being that we don't flag, e.g., an `itertools.pairwise` that uses an extremely large value for the slice start constant). For simplicity, a few diagnostics now show a dedicated message when they see integers that are out of the supported range (e.g., `outdated-version-block`). An additional benefit here is that we get to remove a few dependencies, especially `num-bigint`. ## Test Plan `cargo test`
This commit is contained in:
parent
65aebf127a
commit
93b5d8a0fb
40 changed files with 707 additions and 385 deletions
|
@ -1,7 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
use std::path::Path;
|
||||
|
||||
use num_traits::Zero;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
@ -1073,7 +1072,7 @@ impl Truthiness {
|
|||
Constant::None => Some(false),
|
||||
Constant::Str(ast::StringConstant { value, .. }) => Some(!value.is_empty()),
|
||||
Constant::Bytes(bytes) => Some(!bytes.is_empty()),
|
||||
Constant::Int(int) => Some(!int.is_zero()),
|
||||
Constant::Int(int) => Some(*int != 0),
|
||||
Constant::Float(float) => Some(*float != 0.0),
|
||||
Constant::Complex { real, imag } => Some(*real != 0.0 || *imag != 0.0),
|
||||
Constant::Ellipsis => Some(true),
|
||||
|
@ -1140,7 +1139,7 @@ mod tests {
|
|||
|
||||
use crate::helpers::{any_over_stmt, any_over_type_param, resolve_imported_module_path};
|
||||
use crate::{
|
||||
Constant, Expr, ExprConstant, ExprContext, ExprName, Identifier, Stmt, StmtTypeAlias,
|
||||
Constant, Expr, ExprConstant, ExprContext, ExprName, Identifier, Int, Stmt, StmtTypeAlias,
|
||||
TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams,
|
||||
};
|
||||
|
||||
|
@ -1240,7 +1239,7 @@ mod tests {
|
|||
assert!(!any_over_type_param(&type_var_no_bound, &|_expr| true));
|
||||
|
||||
let bound = Expr::Constant(ExprConstant {
|
||||
value: Constant::Int(1.into()),
|
||||
value: Constant::Int(Int::ONE),
|
||||
range: TextRange::default(),
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue