Skip to content

Commit

Permalink
Auto merge of rust-lang#13200 - Jarcho:constant_no_typeck, r=Alexendoo
Browse files Browse the repository at this point in the history
Don't use `LateContext` in the constant evaluator

This also changes the interface to require explicitly creating the context. `constant` could be added back in, but the others are probably not worth it.

A couple of bugs have been fixed. The wrong `TypeckResults` was used once when evaluating a constant, and the wrong `ParamEnv` was used by some callers (there wasn't a way to use the correct one).

changelog: none
  • Loading branch information
bors committed Aug 8, 2024
2 parents ffc391c + e4ad36d commit b1e8792
Show file tree
Hide file tree
Showing 54 changed files with 395 additions and 386 deletions.
4 changes: 2 additions & 2 deletions clippy_lints/src/assertions_on_constants.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::is_inside_always_const_context;
use clippy_utils::macros::{find_assert_args, root_macro_call_first_node, PanicExpn};
Expand Down Expand Up @@ -43,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants {
let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn) else {
return;
};
let Some(Constant::Bool(val)) = constant(cx, cx.typeck_results(), condition) else {
let Some(Constant::Bool(val)) = ConstEvalCtxt::new(cx).eval(condition) else {
return;
};

Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/casts/cast_nan_to_int.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::CAST_NAN_TO_INT;

use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_note;
use rustc_hir::Expr;
use rustc_lint::LateContext;
Expand All @@ -20,7 +20,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
}

fn is_known_nan(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
match constant(cx, cx.typeck_results(), e) {
match ConstEvalCtxt::new(cx).eval(e) {
// FIXME(f16_f128): add these types when nan checks are available on all platforms
Some(Constant::F64(n)) => n.is_nan(),
Some(Constant::F32(n)) => n.is_nan(),
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/casts/cast_possible_truncation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
use clippy_utils::expr_or_init;
use clippy_utils::source::snippet;
Expand All @@ -15,7 +15,7 @@ use rustc_target::abi::IntegerType;
use super::{utils, CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION};

fn constant_int(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<u128> {
if let Some(Constant::Int(c)) = constant(cx, cx.typeck_results(), expr) {
if let Some(Constant::Int(c)) = ConstEvalCtxt::new(cx).eval(expr) {
Some(c)
} else {
None
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/casts/cast_sign_loss.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::convert::Infallible;
use std::ops::ControlFlow;

use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::visitors::{for_each_expr_without_closures, Descend};
use clippy_utils::{method_chain_args, sext};
Expand Down Expand Up @@ -88,7 +88,7 @@ fn get_const_signed_int_eval<'cx>(
) -> Option<i128> {
let ty = ty.into().unwrap_or_else(|| cx.typeck_results().expr_ty(expr));

if let Constant::Int(n) = constant(cx, cx.typeck_results(), expr)?
if let Constant::Int(n) = ConstEvalCtxt::new(cx).eval(expr)?
&& let ty::Int(ity) = *ty.kind()
{
return Some(sext(cx.tcx, n, ity));
Expand All @@ -103,7 +103,7 @@ fn get_const_unsigned_int_eval<'cx>(
) -> Option<u128> {
let ty = ty.into().unwrap_or_else(|| cx.typeck_results().expr_ty(expr));

if let Constant::Int(n) = constant(cx, cx.typeck_results(), expr)?
if let Constant::Int(n) = ConstEvalCtxt::new(cx).eval(expr)?
&& let ty::Uint(_ity) = *ty.kind()
{
return Some(n);
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/enum_clike.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant {
.const_eval_poly(def_id.to_def_id())
.ok()
.map(|val| rustc_middle::mir::Const::from_value(val, ty));
if let Some(Constant::Int(val)) = constant.and_then(|c| mir_to_const(cx, c)) {
if let Some(Constant::Int(val)) = constant.and_then(|c| mir_to_const(cx.tcx, c)) {
if let ty::Adt(adt, _) = ty.kind() {
if adt.is_enum() {
ty = adt.repr().discr_type().to_ty(cx.tcx);
Expand Down
30 changes: 15 additions & 15 deletions clippy_lints/src/floating_point_arithmetic.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clippy_utils::consts::Constant::{Int, F32, F64};
use clippy_utils::consts::{constant, constant_simple, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::{
eq_expr_value, get_parent_expr, higher, is_in_const_context, is_inherent_method_call, is_no_std_crate,
Expand Down Expand Up @@ -112,7 +112,7 @@ declare_lint_pass!(FloatingPointArithmetic => [
// Returns the specialized log method for a given base if base is constant
// and is one of 2, 10 and e
fn get_specialized_log_method(cx: &LateContext<'_>, base: &Expr<'_>) -> Option<&'static str> {
if let Some(value) = constant(cx, cx.typeck_results(), base) {
if let Some(value) = ConstEvalCtxt::new(cx).eval(base) {
if F32(2.0) == value || F64(2.0) == value {
return Some("log2");
} else if F32(10.0) == value || F64(10.0) == value {
Expand Down Expand Up @@ -182,10 +182,8 @@ fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) {
rhs,
) = receiver.kind
{
let recv = match (
constant(cx, cx.typeck_results(), lhs),
constant(cx, cx.typeck_results(), rhs),
) {
let ecx = ConstEvalCtxt::new(cx);
let recv = match (ecx.eval(lhs), ecx.eval(rhs)) {
(Some(value), _) if F32(1.0) == value || F64(1.0) == value => rhs,
(_, Some(value)) if F32(1.0) == value || F64(1.0) == value => lhs,
_ => return,
Expand Down Expand Up @@ -230,7 +228,7 @@ fn get_integer_from_float_constant(value: &Constant<'_>) -> Option<i32> {

fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) {
// Check receiver
if let Some(value) = constant(cx, cx.typeck_results(), receiver) {
if let Some(value) = ConstEvalCtxt::new(cx).eval(receiver) {
if let Some(method) = if F32(f32_consts::E) == value || F64(f64_consts::E) == value {
Some("exp")
} else if F32(2.0) == value || F64(2.0) == value {
Expand All @@ -251,7 +249,7 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args:
}

// Check argument
if let Some(value) = constant(cx, cx.typeck_results(), &args[0]) {
if let Some(value) = ConstEvalCtxt::new(cx).eval(&args[0]) {
let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value {
(
SUBOPTIMAL_FLOPS,
Expand Down Expand Up @@ -291,7 +289,7 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args:
}

fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) {
if let Some(value) = constant(cx, cx.typeck_results(), &args[0]) {
if let Some(value) = ConstEvalCtxt::new(cx).eval(&args[0]) {
if value == Int(2) {
if let Some(parent) = get_parent_expr(cx, expr) {
if let Some(grandparent) = get_parent_expr(cx, parent) {
Expand Down Expand Up @@ -397,8 +395,9 @@ fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option<String> {
) = &add_rhs.kind
&& lmethod_name.as_str() == "powi"
&& rmethod_name.as_str() == "powi"
&& let Some(lvalue) = constant(cx, cx.typeck_results(), largs_1)
&& let Some(rvalue) = constant(cx, cx.typeck_results(), rargs_1)
&& let ecx = ConstEvalCtxt::new(cx)
&& let Some(lvalue) = ecx.eval(largs_1)
&& let Some(rvalue) = ecx.eval(rargs_1)
&& Int(2) == lvalue
&& Int(2) == rvalue
{
Expand Down Expand Up @@ -438,7 +437,7 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) {
rhs,
) = expr.kind
&& cx.typeck_results().expr_ty(lhs).is_floating_point()
&& let Some(value) = constant(cx, cx.typeck_results(), rhs)
&& let Some(value) = ConstEvalCtxt::new(cx).eval(rhs)
&& (F32(1.0) == value || F64(1.0) == value)
&& let ExprKind::MethodCall(path, self_arg, ..) = &lhs.kind
&& cx.typeck_results().expr_ty(self_arg).is_floating_point()
Expand Down Expand Up @@ -552,7 +551,7 @@ fn is_testing_negative(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -

/// Returns true iff expr is some zero literal
fn is_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
match constant_simple(cx, cx.typeck_results(), expr) {
match ConstEvalCtxt::new(cx).eval_simple(expr) {
Some(Int(i)) => i == 0,
Some(F32(f)) => f == 0.0,
Some(F64(f)) => f == 0.0,
Expand Down Expand Up @@ -696,8 +695,9 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) {
mul_lhs,
mul_rhs,
) = &div_lhs.kind
&& let Some(rvalue) = constant(cx, cx.typeck_results(), div_rhs)
&& let Some(lvalue) = constant(cx, cx.typeck_results(), mul_rhs)
&& let ecx = ConstEvalCtxt::new(cx)
&& let Some(rvalue) = ecx.eval(div_rhs)
&& let Some(lvalue) = ecx.eval(mul_rhs)
{
// TODO: also check for constant values near PI/180 or 180/PI
if (F32(f32_consts::PI) == rvalue || F64(f64_consts::PI) == rvalue)
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/if_not_else.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! lint on if branches that could be swapped so no `!` operation is necessary
//! on the condition

use clippy_utils::consts::{constant_simple, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::is_else_clause;
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
Expand Down Expand Up @@ -49,7 +49,7 @@ declare_clippy_lint! {
declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]);

fn is_zero_const(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool {
if let Some(value) = constant_simple(cx, cx.typeck_results(), expr) {
if let Some(value) = ConstEvalCtxt::new(cx).eval_simple(expr) {
return Constant::Int(0) == value;
}
false
Expand Down
8 changes: 4 additions & 4 deletions clippy_lints/src/implicit_saturating_add.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::get_parent_expr;
use clippy_utils::source::snippet_with_context;
Expand Down Expand Up @@ -117,11 +117,11 @@ fn get_int_max(ty: Ty<'_>) -> Option<u128> {

fn get_const<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<(u128, BinOpKind, &'tcx Expr<'tcx>)> {
if let ExprKind::Binary(op, l, r) = expr.kind {
let tr = cx.typeck_results();
if let Some(Constant::Int(c)) = constant(cx, tr, r) {
let ecx = ConstEvalCtxt::new(cx);
if let Some(Constant::Int(c)) = ecx.eval(r) {
return Some((c, op.node, l));
};
if let Some(Constant::Int(c)) = constant(cx, tr, l) {
if let Some(Constant::Int(c)) = ecx.eval(l) {
return Some((c, invert_op(op.node)?, r));
}
}
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/index_refutable_slice.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_config::Conf;
use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::IfLet;
use clippy_utils::ty::is_copy;
Expand Down Expand Up @@ -246,7 +246,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
&& let parent_id = cx.tcx.parent_hir_id(expr.hir_id)
&& let hir::Node::Expr(parent_expr) = cx.tcx.hir_node(parent_id)
&& let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind
&& let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr)
&& let Some(Constant::Int(index_value)) = ConstEvalCtxt::new(cx).eval(index_expr)
&& let Ok(index_value) = index_value.try_into()
&& index_value < max_suggested_slice

Expand Down
9 changes: 5 additions & 4 deletions clippy_lints/src/indexing_slicing.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! lint on indexing and slicing operations

use clippy_config::Conf;
use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
use clippy_utils::ty::{deref_chain, get_adt_inherent_method};
use clippy_utils::{higher, is_from_proc_macro};
Expand Down Expand Up @@ -177,7 +177,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
return;
}
// Index is a constant uint.
if let Some(constant) = constant(cx, cx.typeck_results(), index) {
if let Some(constant) = ConstEvalCtxt::new(cx).eval(index) {
// only `usize` index is legal in rust array index
// leave other type to rustc
if let Constant::Int(off) = constant
Expand Down Expand Up @@ -215,14 +215,15 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
/// Returns a tuple of options with the start and end (exclusive) values of
/// the range. If the start or end is not constant, None is returned.
fn to_const_range(cx: &LateContext<'_>, range: higher::Range<'_>, array_size: u128) -> (Option<u128>, Option<u128>) {
let s = range.start.map(|expr| constant(cx, cx.typeck_results(), expr));
let ecx = ConstEvalCtxt::new(cx);
let s = range.start.map(|expr| ecx.eval(expr));
let start = match s {
Some(Some(Constant::Int(x))) => Some(x),
Some(_) => None,
None => Some(0),
};

let e = range.end.map(|expr| constant(cx, cx.typeck_results(), expr));
let e = range.end.map(|expr| ecx.eval(expr));
let end = match e {
Some(Some(Constant::Int(x))) => {
if range.limits == RangeLimits::Closed {
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/invalid_upcast_comparisons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_span::Span;

use clippy_utils::comparisons;
use clippy_utils::comparisons::Rel;
use clippy_utils::consts::{constant_full_int, FullInt};
use clippy_utils::consts::{ConstEvalCtxt, FullInt};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::source::snippet;

Expand Down Expand Up @@ -95,7 +95,7 @@ fn upcast_comparison_bounds_err<'tcx>(
invert: bool,
) {
if let Some((lb, ub)) = lhs_bounds {
if let Some(norm_rhs_val) = constant_full_int(cx, cx.typeck_results(), rhs) {
if let Some(norm_rhs_val) = ConstEvalCtxt::new(cx).eval_full_int(rhs) {
if rel == Rel::Eq || rel == Rel::Ne {
if norm_rhs_val < lb || norm_rhs_val > ub {
err_upcast_comparison(cx, span, lhs, rel == Rel::Ne);
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/loops/while_immutable_condition.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::WHILE_IMMUTABLE_CONDITION;
use clippy_utils::consts::constant;
use clippy_utils::consts::ConstEvalCtxt;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::usage::mutated_variables;
use rustc_hir::def::{DefKind, Res};
Expand All @@ -10,7 +10,7 @@ use rustc_lint::LateContext;
use std::ops::ControlFlow;

pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) {
if constant(cx, cx.typeck_results(), cond).is_some() {
if ConstEvalCtxt::new(cx).eval(cond).is_some() {
// A pure constant condition (e.g., `while false`) is not linted.
return;
}
Expand Down
7 changes: 4 additions & 3 deletions clippy_lints/src/manual_clamp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_config::Conf;
use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
use clippy_utils::higher::If;
use clippy_utils::sugg::Sugg;
Expand Down Expand Up @@ -122,8 +122,9 @@ impl<'tcx> ClampSuggestion<'tcx> {
if max_type != min_type {
return false;
}
if let Some(max) = constant(cx, cx.typeck_results(), self.params.max)
&& let Some(min) = constant(cx, cx.typeck_results(), self.params.min)
let ecx = ConstEvalCtxt::new(cx);
if let Some(max) = ecx.eval(self.params.max)
&& let Some(min) = ecx.eval(self.params.min)
&& let Some(ord) = Constant::partial_cmp(cx.tcx, max_type, &min, &max)
{
ord != Ordering::Greater
Expand Down
7 changes: 4 additions & 3 deletions clippy_lints/src/manual_float_methods.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_opt;
use clippy_utils::{is_from_proc_macro, path_to_local};
Expand Down Expand Up @@ -95,8 +95,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|| cx.tcx.features().declared(sym!(const_float_classify))
)
&& let [first, second, const_1, const_2] = exprs
&& let Some(const_1) = constant(cx, cx.typeck_results(), const_1)
&& let Some(const_2) = constant(cx, cx.typeck_results(), const_2)
&& let ecx = ConstEvalCtxt::new(cx)
&& let Some(const_1) = ecx.eval(const_1)
&& let Some(const_2) = ecx.eval(const_2)
&& path_to_local(first).is_some_and(|f| path_to_local(second).is_some_and(|s| f == s))
// The actual infinity check, we also allow `NEG_INFINITY` before` INFINITY` just in
// case somebody does that for some reason
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/manual_rem_euclid.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_config::Conf;
use clippy_utils::consts::{constant_full_int, FullInt};
use clippy_utils::consts::{ConstEvalCtxt, FullInt};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_context;
use clippy_utils::{is_in_const_context, path_to_local};
Expand Down Expand Up @@ -117,7 +117,7 @@ fn check_for_either_unsigned_int_constant<'a>(
}

fn check_for_unsigned_int_constant<'a>(cx: &'a LateContext<'_>, expr: &'a Expr<'_>) -> Option<u128> {
let int_const = constant_full_int(cx, cx.typeck_results(), expr)?;
let int_const = ConstEvalCtxt::new(cx).eval_full_int(expr)?;
match int_const {
FullInt::S(s) => s.try_into().ok(),
FullInt::U(u) => Some(u),
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/manual_rotate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt::Display;

use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::sugg;
use rustc_errors::Applicability;
Expand Down Expand Up @@ -66,7 +66,7 @@ fn parse_shift<'tcx>(
BinOpKind::Shr => ShiftDirection::Right,
_ => return None,
};
let const_expr = constant(cx, cx.typeck_results(), r)?;
let const_expr = ConstEvalCtxt::new(cx).eval(r)?;
if let Constant::Int(shift) = const_expr {
return Some((dir, shift, l));
}
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/manual_strip.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_config::Conf;
use clippy_utils::consts::{constant, Constant};
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet;
use clippy_utils::usage::mutated_variables;
Expand Down Expand Up @@ -147,7 +147,7 @@ fn len_arg<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx E

// Returns the length of the `expr` if it's a constant string or char.
fn constant_length(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<u128> {
let value = constant(cx, cx.typeck_results(), expr)?;
let value = ConstEvalCtxt::new(cx).eval(expr)?;
match value {
Constant::Str(value) => Some(value.len() as u128),
Constant::Char(value) => Some(value.len_utf8() as u128),
Expand Down
Loading

0 comments on commit b1e8792

Please sign in to comment.