Skip to content

Commit 6cb40f1

Browse files
refactor: use add core crate constant source
1 parent e8e3722 commit 6cb40f1

File tree

4 files changed

+79
-69
lines changed

4 files changed

+79
-69
lines changed

clippy_lints/src/methods/unnecessary_min_or_max.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@ use std::cmp::Ordering;
33
use super::UNNECESSARY_MIN_OR_MAX;
44
use clippy_utils::diagnostics::span_lint_and_sugg;
55

6-
use clippy_utils::consts::{constant, ConstEvalLateContext, Constant, FullInt};
6+
use clippy_utils::consts::{constant, constant_with_source, Constant, ConstantSource, FullInt};
77
use clippy_utils::source::snippet;
88

99
use rustc_errors::Applicability;
1010
use rustc_hir::Expr;
1111
use rustc_lint::LateContext;
12-
1312
use rustc_middle::ty;
14-
use rustc_span::{sym, Span};
13+
use rustc_span::Span;
1514

1615
pub(super) fn check<'tcx>(
1716
cx: &LateContext<'tcx>,
@@ -91,6 +90,11 @@ fn detect_extrema<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<
9190
}
9291

9392
fn is_external_const(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
94-
let mut ctxt = ConstEvalLateContext::new(cx, cx.typeck_results());
95-
ctxt.expr(expr).is_some() && ctxt.expr_is_external(expr, &[sym::core])
93+
let cv_src = constant_with_source(cx, cx.typeck_results(), expr);
94+
let Some((_, const_src)) = cv_src else { return false };
95+
96+
!matches!(
97+
const_src,
98+
ConstantSource::LocalOrCoreCrateConstant | ConstantSource::Local
99+
)
96100
}

clippy_utils/src/consts.rs

Lines changed: 13 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_middle::ty::{self, EarlyBinder, FloatTy, GenericArgsRef, IntTy, List,
1616
use rustc_middle::{bug, mir, span_bug};
1717
use rustc_span::def_id::DefId;
1818
use rustc_span::symbol::{Ident, Symbol};
19-
use rustc_span::SyntaxContext;
19+
use rustc_span::{sym, SyntaxContext};
2020
use rustc_target::abi::Size;
2121
use std::cmp::Ordering;
2222
use std::hash::{Hash, Hasher};
@@ -303,6 +303,8 @@ pub enum ConstantSource {
303303
Local,
304304
/// The value is dependent on a defined constant.
305305
Constant,
306+
/// The value is dependent on a constant defined in current crate of `core` crate.
307+
LocalOrCoreCrateConstant,
306308
}
307309
impl ConstantSource {
308310
pub fn is_local(&self) -> bool {
@@ -416,9 +418,18 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
416418
ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.lcx.tcx.hir().body(body).value),
417419
ExprKind::DropTemps(e) => self.expr(e),
418420
ExprKind::Path(ref qpath) => {
421+
let is_local_or_core_crate = if let Some(def_id) = self.lcx.qpath_res(qpath, e.hir_id()).opt_def_id() {
422+
def_id.is_local() || self.lcx.tcx.crate_name(def_id.krate) == sym::core
423+
} else {
424+
false
425+
};
419426
self.fetch_path_and_apply(qpath, e.hir_id, self.typeck_results.expr_ty(e), |this, result| {
420427
let result = mir_to_const(this.lcx, result)?;
421-
this.source = ConstantSource::Constant;
428+
this.source = if is_local_or_core_crate {
429+
ConstantSource::LocalOrCoreCrateConstant
430+
} else {
431+
ConstantSource::Constant
432+
};
422433
Some(result)
423434
})
424435
},
@@ -530,59 +541,6 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
530541
}
531542
}
532543

533-
/// Simple constant folding to determine if an expression depends on an external crate
534-
/// excluding crates listed in exceptions
535-
pub fn expr_is_external(&mut self, e: &Expr<'_>, exceptions: &[Symbol]) -> bool {
536-
match e.kind {
537-
ExprKind::ConstBlock(ConstBlock { body, .. }) => {
538-
self.expr_is_external(self.lcx.tcx.hir().body(body).value, exceptions)
539-
},
540-
ExprKind::DropTemps(e) => self.expr_is_external(e, exceptions),
541-
ExprKind::Path(ref qpath) => {
542-
if let Some(def_id) = self.lcx.qpath_res(qpath, e.hir_id()).opt_def_id() {
543-
def_id.is_local() || exceptions.iter().all(|e| self.lcx.tcx.crate_name(def_id.krate) != *e)
544-
} else {
545-
true
546-
}
547-
},
548-
ExprKind::Block(block, _) => {
549-
if block.stmts.is_empty()
550-
&& let Some(expr) = block.expr
551-
{
552-
self.expr_is_external(expr, exceptions)
553-
} else {
554-
false
555-
}
556-
},
557-
ExprKind::Array(vec) => vec.iter().any(|elem| self.expr_is_external(elem, exceptions)),
558-
ExprKind::Tup(tup) => tup.iter().any(|elem| self.expr_is_external(elem, exceptions)),
559-
ExprKind::Repeat(value, _) => self.expr_is_external(value, exceptions),
560-
ExprKind::Unary(_, operand) => self.expr_is_external(operand, exceptions),
561-
ExprKind::If(cond, then, ref otherwise) => {
562-
if let Some(Constant::Bool(b)) = self.expr(cond) {
563-
if b {
564-
self.expr_is_external(then, exceptions)
565-
} else {
566-
otherwise
567-
.as_ref()
568-
.is_some_and(|expr| self.expr_is_external(expr, exceptions))
569-
}
570-
} else {
571-
false
572-
}
573-
},
574-
ExprKind::Binary(_, left, right) => {
575-
self.expr_is_external(left, exceptions) || self.expr_is_external(right, exceptions)
576-
},
577-
ExprKind::Index(arr, index, _) => {
578-
self.expr_is_external(arr, exceptions) || self.expr_is_external(index, exceptions)
579-
},
580-
ExprKind::AddrOf(_, _, inner) => self.expr_is_external(inner, exceptions),
581-
ExprKind::Field(local_expr, _) => self.expr_is_external(local_expr, exceptions),
582-
_ => false,
583-
}
584-
}
585-
586544
#[expect(clippy::cast_possible_wrap)]
587545
fn constant_not(&self, o: &Constant<'tcx>, ty: Ty<'_>) -> Option<Constant<'tcx>> {
588546
use self::Constant::{Bool, Int};

tests/ui/unnecessary_min_or_max.fixed

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ fn main() {
1212
let _ = 6;
1313
let _ = 7_u8;
1414

15-
let _ = X.max(12);
16-
let _ = X.min(12);
17-
let _ = 12.min(X);
18-
let _ = 12.max(X);
19-
let _ = (X + 1).max(12);
20-
let _ = (X + 1).min(12);
21-
let _ = 12.min(X - 1);
22-
let _ = 12.max(X - 1);
15+
let _ = 12;
16+
let _ = X;
17+
let _ = X;
18+
let _ = 12;
19+
let _ = 12;
20+
let _ = (X + 1);
21+
let _ = X - 1;
22+
let _ = 12;
2323

2424
let x: u32 = 42;
2525
// unsigned with zero

tests/ui/unnecessary_min_or_max.stderr

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,54 @@ error: `6` is never greater than `7_u8` and has therefore no effect
3737
LL | let _ = 6.max(7_u8);
3838
| ^^^^^^^^^^^ help: try: `7_u8`
3939

40+
error: `X` is never greater than `12` and has therefore no effect
41+
--> tests/ui/unnecessary_min_or_max.rs:15:13
42+
|
43+
LL | let _ = X.max(12);
44+
| ^^^^^^^^^ help: try: `12`
45+
46+
error: `X` is never greater than `12` and has therefore no effect
47+
--> tests/ui/unnecessary_min_or_max.rs:16:13
48+
|
49+
LL | let _ = X.min(12);
50+
| ^^^^^^^^^ help: try: `X`
51+
52+
error: `12` is never smaller than `X` and has therefore no effect
53+
--> tests/ui/unnecessary_min_or_max.rs:17:13
54+
|
55+
LL | let _ = 12.min(X);
56+
| ^^^^^^^^^ help: try: `X`
57+
58+
error: `12` is never smaller than `X` and has therefore no effect
59+
--> tests/ui/unnecessary_min_or_max.rs:18:13
60+
|
61+
LL | let _ = 12.max(X);
62+
| ^^^^^^^^^ help: try: `12`
63+
64+
error: `(X + 1)` is never greater than `12` and has therefore no effect
65+
--> tests/ui/unnecessary_min_or_max.rs:19:13
66+
|
67+
LL | let _ = (X + 1).max(12);
68+
| ^^^^^^^^^^^^^^^ help: try: `12`
69+
70+
error: `(X + 1)` is never greater than `12` and has therefore no effect
71+
--> tests/ui/unnecessary_min_or_max.rs:20:13
72+
|
73+
LL | let _ = (X + 1).min(12);
74+
| ^^^^^^^^^^^^^^^ help: try: `(X + 1)`
75+
76+
error: `12` is never smaller than `X - 1` and has therefore no effect
77+
--> tests/ui/unnecessary_min_or_max.rs:21:13
78+
|
79+
LL | let _ = 12.min(X - 1);
80+
| ^^^^^^^^^^^^^ help: try: `X - 1`
81+
82+
error: `12` is never smaller than `X - 1` and has therefore no effect
83+
--> tests/ui/unnecessary_min_or_max.rs:22:13
84+
|
85+
LL | let _ = 12.max(X - 1);
86+
| ^^^^^^^^^^^^^ help: try: `12`
87+
4088
error: `0` is never greater than `x` and has therefore no effect
4189
--> tests/ui/unnecessary_min_or_max.rs:26:13
4290
|
@@ -103,5 +151,5 @@ error: `x` is never smaller than `i32::MIN - 0` and has therefore no effect
103151
LL | let _ = x.min(i32::MIN - 0);
104152
| ^^^^^^^^^^^^^^^^^^^ help: try: `i32::MIN - 0`
105153

106-
error: aborting due to 17 previous errors
154+
error: aborting due to 25 previous errors
107155

0 commit comments

Comments
 (0)