Skip to content

Commit

Permalink
Introduce ::Likely
Browse files Browse the repository at this point in the history
  • Loading branch information
InSyncWithFoo committed Dec 7, 2024
1 parent 86e00a8 commit 37e9acf
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 840 deletions.
60 changes: 30 additions & 30 deletions crates/ruff_linter/resources/test/fixtures/ruff/RUF046.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,45 @@
int(math.floor())
int(math.trunc())


### No errors

int(1 and 0)
int(0 or -1)

int(foo if ... else 4)

int(round())
int(round(ndigits=2))
int(round(3.4))
int(round(3.4, 0))
int(round(3.4, 2))
int(round(5, foo))

int(3.14)
int(2.8j)

async def f():
int(await f())

int(foo.bar)
int(bar([1][False]))

int(1 == 1)
int(1 != 1)
int(1 < 1)
int(1 <= 1)
int(1 > 1)
int(1 >= 1)
int(1 in 1)
int(1 not in 1)
int(1 is 1)
int(2 is not 3)
int(foo in 1)
int(foo not in 1)
int(foo is 1)
int(foo is not 1)

int(1 == 2 == 3)
int(foo == 1)
int(foo != 1)
Expand All @@ -80,36 +110,6 @@ async def f():
int(foo & 1)
int(foo // 1)

int(foo if ... else 4)

int(round())
int(round(ndigits=2))
int(round(3.4))
int(round(3.4, 0))
int(round(3.4, 2))
int(round(5, foo))


### No errors

int(3.14)
int(2.8j)

int(1 == 1)
int(1 != 1)
int(1 < 1)
int(1 <= 1)
int(1 > 1)
int(1 >= 1)
int(1 in 1)
int(1 not in 1)
int(1 is 1)
int(2 is not 3)
int(foo in 1)
int(foo not in 1)
int(foo is 1)
int(foo is not 1)

int(v := 3.7)

int(not 109)
Expand Down
9 changes: 5 additions & 4 deletions crates/ruff_linter/resources/test/fixtures/ruff/RUF057.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@
round(1, ndigits=0)
round(number=1, ndigits=0)

round(1, None)
round(1, ndigits=None)
round(number=1, ndigits=None)

round(1., 0)
round(1., ndigits=0)
round(number=1., ndigits=0)

round(1., None)
round(1., ndigits=None)
round(number=1., ndigits=None)
Expand All @@ -26,6 +23,10 @@

### No errors

round(1., 0)
round(1., ndigits=0)
round(number=1., ndigits=0)

round(1, 1)
round(1, bar)
round(1., bar)
Expand Down
28 changes: 18 additions & 10 deletions crates/ruff_linter/src/rules/ruff/rules/unnecessary_cast_to_int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ impl AlwaysFixableViolation for UnnecessaryCastToInt {
#[derive(Debug, PartialEq, Eq, Clone, Copy, is_macro::Is)]
pub(crate) enum IsStrictlyInt {
/// The value is known with absolute certainty to be a strict instance of `int`.
#[is(name = "true")]
True,
/// The value is known with absolute certainty to *not* be a strict instance of `int`.
#[is(name = "false")]
False,
/// It is not possible to statically determine that the value is a strict instance of `int`.
#[is(name = "maybe")]
/// The evaluation context has a high chance of producing a strict instance of `int`.
Likely,
/// It is not possible to statically determine that the value
/// is or is not a strict instance of `int`.
Maybe,
}

Expand All @@ -79,8 +79,8 @@ pub(crate) fn unnecessary_cast_to_int(checker: &mut Checker, call: &ExprCall) {

let applicability = match expr_is_strictly_int(semantic, argument) {
IsStrictlyInt::True => Applicability::Safe,
IsStrictlyInt::Maybe => Applicability::Unsafe,
IsStrictlyInt::False => return,
IsStrictlyInt::Likely => Applicability::Unsafe,
_ => return,
};

let edit = replace_with_inner(checker.locator(), call.range, argument.range());
Expand Down Expand Up @@ -177,6 +177,11 @@ pub(crate) fn expr_is_strictly_int(semantic: &SemanticModel, expr: &Expr) -> IsS
Operator::MatMult => IsStrictlyInt::False,
_ => IsStrictlyInt::True,
},
[IsStrictlyInt::Likely, IsStrictlyInt::Likely] => match op {
Operator::Div => IsStrictlyInt::Maybe,
Operator::MatMult => IsStrictlyInt::Maybe,
_ => IsStrictlyInt::Likely,
},
_ => IsStrictlyInt::Maybe,
}
}
Expand All @@ -187,6 +192,7 @@ pub(crate) fn expr_is_strictly_int(semantic: &SemanticModel, expr: &Expr) -> IsS

match [body_is_strictly_int, else_is_strictly_int] {
[IsStrictlyInt::True, IsStrictlyInt::True] => IsStrictlyInt::True,
[IsStrictlyInt::Likely, IsStrictlyInt::Likely] => IsStrictlyInt::Likely,
[IsStrictlyInt::False, IsStrictlyInt::False] => IsStrictlyInt::False,
_ => IsStrictlyInt::Maybe,
}
Expand Down Expand Up @@ -241,7 +247,7 @@ fn call_strictly_returns_int(semantic: &SemanticModel, call: &ExprCall) -> IsStr
| ["math", "comb" | "factorial" | "gcd" | "lcm" | "isqrt" | "perm"] => IsStrictlyInt::True,

// Depends on `__ceil__`/`__floor__`/`__trunc__`
["math", "ceil" | "floor" | "trunc"] => IsStrictlyInt::Maybe,
["math", "ceil" | "floor" | "trunc"] => IsStrictlyInt::Likely,

// Depends on `ndigits` and `number.__round__`
["" | "builtins", "round"] => round_call_strictly_returns_int(semantic, arguments),
Expand All @@ -265,14 +271,16 @@ fn round_call_strictly_returns_int(
return IsStrictlyInt::Maybe;
};

match expr_is_strictly_int(semantic, number) {
let number_is_strictly_int = expr_is_strictly_int(semantic, number);

match number_is_strictly_int {
IsStrictlyInt::Maybe => return IsStrictlyInt::Maybe,
IsStrictlyInt::False => return IsStrictlyInt::Maybe,
IsStrictlyInt::True => {}
_ => {}
};

match ndigits {
None | Some(Expr::NoneLiteral(..)) => IsStrictlyInt::True,
None | Some(Expr::NoneLiteral(..)) => number_is_strictly_int,

Some(Expr::NumberLiteral(ExprNumberLiteral { value, .. })) => {
if is_literal_zero(value) {
Expand Down
Loading

0 comments on commit 37e9acf

Please sign in to comment.