Replace `is_integer_const` with `eval_int`.
diff --git a/clippy_lints/src/operators/modulo_one.rs b/clippy_lints/src/operators/modulo_one.rs
index 2e6a071..22ec8b1 100644
--- a/clippy_lints/src/operators/modulo_one.rs
+++ b/clippy_lints/src/operators/modulo_one.rs
@@ -1,26 +1,17 @@
+use clippy_utils::consts::{FullInt, eval_int};
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::{is_integer_const, unsext};
 use rustc_hir::{BinOpKind, Expr};
 use rustc_lint::LateContext;
-use rustc_middle::ty;
 
 use super::MODULO_ONE;
 
 pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, op: BinOpKind, right: &Expr<'_>) {
     if op == BinOpKind::Rem {
-        if is_integer_const(cx, right, 1) {
-            span_lint(cx, MODULO_ONE, expr.span, "any number modulo 1 will be 0");
-        }
-
-        if let ty::Int(ity) = cx.typeck_results().expr_ty(right).kind()
-            && is_integer_const(cx, right, unsext(cx.tcx, -1, *ity))
-        {
-            span_lint(
-                cx,
-                MODULO_ONE,
-                expr.span,
-                "any number modulo -1 will panic/overflow or result in 0",
-            );
-        }
+        let msg = match eval_int(cx, right) {
+            Some(FullInt::S(-1)) => "any number modulo -1 will panic/overflow or result in 0",
+            Some(FullInt::U(1)) => "any number modulo 1 will be 0",
+            _ => return,
+        };
+        span_lint(cx, MODULO_ONE, expr.span, msg);
     }
 }
diff --git a/clippy_lints/src/transmute/transmuting_null.rs b/clippy_lints/src/transmute/transmuting_null.rs
index ed8a099..c85a315 100644
--- a/clippy_lints/src/transmute/transmuting_null.rs
+++ b/clippy_lints/src/transmute/transmuting_null.rs
@@ -1,7 +1,7 @@
-use clippy_utils::consts::{ConstEvalCtxt, Constant};
+use clippy_utils::consts::{ConstEvalCtxt, Constant, FullInt, eval_int};
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::res::{MaybeDef, MaybeResPath};
-use clippy_utils::{is_integer_const, sym};
+use clippy_utils::sym;
 use rustc_hir::{ConstBlock, Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::Ty;
@@ -26,7 +26,7 @@
     // Catching:
     // `std::mem::transmute(0 as *const i32)`
     if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind
-        && is_integer_const(cx, inner_expr, 0)
+        && eval_int(cx, inner_expr).is_some_and(FullInt::is_zero)
     {
         span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
         return true;
@@ -47,7 +47,7 @@
     if let ExprKind::Call(func1, [arg1]) = arg.kind
         && (func1.basic_res().is_diag_item(cx, sym::ptr_without_provenance)
             || func1.basic_res().is_diag_item(cx, sym::ptr_without_provenance_mut))
-        && is_integer_const(cx, arg1, 0)
+        && eval_int(cx, arg1).is_some_and(FullInt::is_zero)
     {
         span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
         return true;
diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs
index 51db6b6..098be98 100644
--- a/clippy_utils/src/consts.rs
+++ b/clippy_utils/src/consts.rs
@@ -462,6 +462,12 @@
     U(u128),
 }
 
+impl FullInt {
+    pub fn is_zero(self) -> bool {
+        matches!(self, Self::S(0) | Self::U(0))
+    }
+}
+
 impl PartialEq for FullInt {
     fn eq(&self, other: &Self) -> bool {
         self.cmp(other) == Ordering::Equal
@@ -491,6 +497,25 @@
     }
 }
 
+/// Evaluates an expression if it's a builtin integer type.
+pub fn eval_int(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<FullInt> {
+    match e.kind {
+        ExprKind::Lit(lit) if let LitKind::Int(val, _) = lit.node => Some(FullInt::U(val.0)),
+        ExprKind::Unary(UnOp::Neg, e)
+            if let ExprKind::Lit(lit) = e.kind
+                && let LitKind::Int(val, _) = lit.node =>
+        {
+            Some(FullInt::S(val.0.cast_signed().wrapping_neg()))
+        },
+        _ if let ty = cx.typeck_results().expr_ty(e)
+            && let ty::Int(_) | ty::Uint(_) = *ty.kind() =>
+        {
+            ConstEvalCtxt::new(cx).eval(e).and_then(|x| x.int_value(cx.tcx, ty))
+        },
+        _ => None,
+    }
+}
+
 /// The context required to evaluate a constant expression.
 ///
 /// This is currently limited to constant folding and reading the value of named constants.
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 717d531..c208b8b 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -120,7 +120,7 @@
 use visitors::{Visitable, for_each_unconsumed_temporary};
 
 use crate::ast_utils::unordered_over;
-use crate::consts::{ConstEvalCtxt, Constant};
+use crate::consts::ConstEvalCtxt;
 use crate::higher::Range;
 use crate::msrvs::Msrv;
 use crate::res::{MaybeDef, MaybeQPath, MaybeResPath};
@@ -1384,24 +1384,8 @@
     false
 }
 
-/// Checks whether the given expression is a constant integer of the given value.
-/// unlike `is_integer_literal`, this version does const folding
-pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool {
-    if is_integer_literal(e, value) {
-        return true;
-    }
-    let enclosing_body = cx.tcx.hir_enclosing_body_owner(e.hir_id);
-    if let Some(Constant::Int(v)) =
-        ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), cx.tcx.typeck(enclosing_body)).eval(e)
-    {
-        return value == v;
-    }
-    false
-}
-
 /// Checks whether the given expression is a constant literal of the given value.
 pub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool {
-    // FIXME: use constant folding
     if let ExprKind::Lit(spanned) = expr.kind
         && let LitKind::Int(v, _) = spanned.node
     {