Avoid passing around an Expr
that is only needed for its HirId and its Span
This commit is contained in:
parent
d1231eabf9
commit
9f5473f7ad
2 changed files with 40 additions and 31 deletions
|
@ -557,7 +557,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
|
|||
}
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Lit(lit) => lint_literal(cx, self, e, lit),
|
||||
hir::ExprKind::Lit(lit) => lint_literal(cx, self, e.hir_id, e.span, lit),
|
||||
hir::ExprKind::Call(path, [l, r])
|
||||
if let ExprKind::Path(ref qpath) = path.kind
|
||||
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use hir::{ExprKind, Node, is_range_literal};
|
||||
use rustc_abi::{Integer, Size};
|
||||
use rustc_hir::HirId;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::layout::IntegerExt;
|
||||
use rustc_middle::{bug, ty};
|
||||
use rustc_span::Span;
|
||||
use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir};
|
||||
|
||||
use crate::LateContext;
|
||||
|
@ -21,21 +23,22 @@ fn lint_overflowing_range_endpoint<'tcx>(
|
|||
lit: &hir::Lit,
|
||||
lit_val: u128,
|
||||
max: u128,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
hir_id: HirId,
|
||||
lit_span: Span,
|
||||
ty: &str,
|
||||
) -> bool {
|
||||
// Look past casts to support cases like `0..256 as u8`
|
||||
let (expr, lit_span) = if let Node::Expr(par_expr) = cx.tcx.parent_hir_node(expr.hir_id)
|
||||
let (hir_id, span) = if let Node::Expr(par_expr) = cx.tcx.parent_hir_node(hir_id)
|
||||
&& let ExprKind::Cast(_, _) = par_expr.kind
|
||||
{
|
||||
(par_expr, expr.span)
|
||||
(par_expr.hir_id, par_expr.span)
|
||||
} else {
|
||||
(expr, expr.span)
|
||||
(hir_id, lit_span)
|
||||
};
|
||||
|
||||
// We only want to handle exclusive (`..`) ranges,
|
||||
// which are represented as `ExprKind::Struct`.
|
||||
let Node::ExprField(field) = cx.tcx.parent_hir_node(expr.hir_id) else { return false };
|
||||
let Node::ExprField(field) = cx.tcx.parent_hir_node(hir_id) else { return false };
|
||||
let Node::Expr(struct_expr) = cx.tcx.parent_hir_node(field.hir_id) else { return false };
|
||||
if !is_range_literal(struct_expr) {
|
||||
return false;
|
||||
|
@ -45,7 +48,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
|
|||
// We can suggest using an inclusive range
|
||||
// (`..=`) instead only if it is the `end` that is
|
||||
// overflowing and only by 1.
|
||||
if !(end.expr.hir_id == expr.hir_id && lit_val - 1 == max) {
|
||||
if !(end.expr.hir_id == hir_id && lit_val - 1 == max) {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -57,7 +60,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
|
|||
_ => bug!(),
|
||||
};
|
||||
|
||||
let sub_sugg = if expr.span.lo() == lit_span.lo() {
|
||||
let sub_sugg = if span.lo() == lit_span.lo() {
|
||||
let Ok(start) = cx.sess().source_map().span_to_snippet(start.span) else { return false };
|
||||
UseInclusiveRange::WithoutParen {
|
||||
sugg: struct_expr.span.shrink_to_lo().to(lit_span.shrink_to_hi()),
|
||||
|
@ -67,7 +70,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
|
|||
}
|
||||
} else {
|
||||
UseInclusiveRange::WithParen {
|
||||
eq_sugg: expr.span.shrink_to_lo(),
|
||||
eq_sugg: span.shrink_to_lo(),
|
||||
lit_sugg: lit_span,
|
||||
literal: lit_val - 1,
|
||||
suffix,
|
||||
|
@ -125,7 +128,8 @@ fn get_bin_hex_repr(cx: &LateContext<'_>, lit: &hir::Lit) -> Option<String> {
|
|||
|
||||
fn report_bin_hex_error(
|
||||
cx: &LateContext<'_>,
|
||||
expr: &hir::Expr<'_>,
|
||||
hir_id: HirId,
|
||||
span: Span,
|
||||
ty: attr::IntType,
|
||||
size: Size,
|
||||
repr_str: String,
|
||||
|
@ -144,11 +148,11 @@ fn report_bin_hex_error(
|
|||
};
|
||||
let sign =
|
||||
if negative { OverflowingBinHexSign::Negative } else { OverflowingBinHexSign::Positive };
|
||||
let sub = get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative).map(
|
||||
let sub = get_type_suggestion(cx.typeck_results().node_type(hir_id), val, negative).map(
|
||||
|suggestion_ty| {
|
||||
if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
|
||||
let (sans_suffix, _) = repr_str.split_at(pos);
|
||||
OverflowingBinHexSub::Suggestion { span: expr.span, suggestion_ty, sans_suffix }
|
||||
OverflowingBinHexSub::Suggestion { span, suggestion_ty, sans_suffix }
|
||||
} else {
|
||||
OverflowingBinHexSub::Help { suggestion_ty }
|
||||
}
|
||||
|
@ -156,7 +160,7 @@ fn report_bin_hex_error(
|
|||
);
|
||||
let sign_bit_sub = (!negative)
|
||||
.then(|| {
|
||||
let ty::Int(int_ty) = cx.typeck_results().node_type(expr.hir_id).kind() else {
|
||||
let ty::Int(int_ty) = cx.typeck_results().node_type(hir_id).kind() else {
|
||||
return None;
|
||||
};
|
||||
|
||||
|
@ -177,7 +181,7 @@ fn report_bin_hex_error(
|
|||
};
|
||||
|
||||
Some(OverflowingBinHexSignBitSub {
|
||||
span: expr.span,
|
||||
span,
|
||||
lit_no_suffix,
|
||||
negative_val: actually.clone(),
|
||||
int_ty: int_ty.name_str(),
|
||||
|
@ -186,7 +190,7 @@ fn report_bin_hex_error(
|
|||
})
|
||||
.flatten();
|
||||
|
||||
cx.emit_span_lint(OVERFLOWING_LITERALS, expr.span, OverflowingBinHex {
|
||||
cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingBinHex {
|
||||
ty: t,
|
||||
lit: repr_str.clone(),
|
||||
dec: val,
|
||||
|
@ -236,7 +240,8 @@ fn literal_to_i128(val: u128, negative: bool) -> Option<i128> {
|
|||
fn lint_int_literal<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
type_limits: &TypeLimits,
|
||||
e: &'tcx hir::Expr<'tcx>,
|
||||
hir_id: HirId,
|
||||
span: Span,
|
||||
lit: &hir::Lit,
|
||||
t: ty::IntTy,
|
||||
v: u128,
|
||||
|
@ -244,7 +249,7 @@ fn lint_int_literal<'tcx>(
|
|||
let int_type = t.normalize(cx.sess().target.pointer_width);
|
||||
let (min, max) = int_ty_range(int_type);
|
||||
let max = max as u128;
|
||||
let negative = type_limits.negated_expr_id == Some(e.hir_id);
|
||||
let negative = type_limits.negated_expr_id == Some(hir_id);
|
||||
|
||||
// Detect literal value out of range [min, max] inclusive
|
||||
// avoiding use of -min to prevent overflow/panic
|
||||
|
@ -252,7 +257,8 @@ fn lint_int_literal<'tcx>(
|
|||
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
|
||||
report_bin_hex_error(
|
||||
cx,
|
||||
e,
|
||||
hir_id,
|
||||
span,
|
||||
attr::IntType::SignedInt(ty::ast_int_ty(t)),
|
||||
Integer::from_int_ty(cx, t).size(),
|
||||
repr_str,
|
||||
|
@ -262,18 +268,18 @@ fn lint_int_literal<'tcx>(
|
|||
return;
|
||||
}
|
||||
|
||||
if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
|
||||
if lint_overflowing_range_endpoint(cx, lit, v, max, hir_id, span, t.name_str()) {
|
||||
// The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
|
||||
return;
|
||||
}
|
||||
|
||||
let span = if negative { type_limits.negated_expr_span.unwrap() } else { e.span };
|
||||
let span = if negative { type_limits.negated_expr_span.unwrap() } else { span };
|
||||
let lit = cx
|
||||
.sess()
|
||||
.source_map()
|
||||
.span_to_snippet(span)
|
||||
.unwrap_or_else(|_| if negative { format!("-{v}") } else { v.to_string() });
|
||||
let help = get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative)
|
||||
let help = get_type_suggestion(cx.typeck_results().node_type(hir_id), v, negative)
|
||||
.map(|suggestion_ty| OverflowingIntHelp { suggestion_ty });
|
||||
|
||||
cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingInt {
|
||||
|
@ -288,7 +294,8 @@ fn lint_int_literal<'tcx>(
|
|||
|
||||
fn lint_uint_literal<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
e: &'tcx hir::Expr<'tcx>,
|
||||
hir_id: HirId,
|
||||
span: Span,
|
||||
lit: &hir::Lit,
|
||||
t: ty::UintTy,
|
||||
) {
|
||||
|
@ -302,7 +309,7 @@ fn lint_uint_literal<'tcx>(
|
|||
};
|
||||
|
||||
if lit_val < min || lit_val > max {
|
||||
if let Node::Expr(par_e) = cx.tcx.parent_hir_node(e.hir_id) {
|
||||
if let Node::Expr(par_e) = cx.tcx.parent_hir_node(hir_id) {
|
||||
match par_e.kind {
|
||||
hir::ExprKind::Cast(..) => {
|
||||
if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {
|
||||
|
@ -316,14 +323,15 @@ fn lint_uint_literal<'tcx>(
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
|
||||
if lint_overflowing_range_endpoint(cx, lit, lit_val, max, hir_id, span, t.name_str()) {
|
||||
// The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
|
||||
return;
|
||||
}
|
||||
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
|
||||
report_bin_hex_error(
|
||||
cx,
|
||||
e,
|
||||
hir_id,
|
||||
span,
|
||||
attr::IntType::UnsignedInt(ty::ast_uint_ty(t)),
|
||||
Integer::from_uint_ty(cx, t).size(),
|
||||
repr_str,
|
||||
|
@ -332,7 +340,7 @@ fn lint_uint_literal<'tcx>(
|
|||
);
|
||||
return;
|
||||
}
|
||||
cx.emit_span_lint(OVERFLOWING_LITERALS, e.span, OverflowingUInt {
|
||||
cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingUInt {
|
||||
ty: t.name_str(),
|
||||
lit: cx
|
||||
.sess()
|
||||
|
@ -348,19 +356,20 @@ fn lint_uint_literal<'tcx>(
|
|||
pub(crate) fn lint_literal<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
type_limits: &TypeLimits,
|
||||
e: &'tcx hir::Expr<'tcx>,
|
||||
hir_id: HirId,
|
||||
span: Span,
|
||||
lit: &hir::Lit,
|
||||
) {
|
||||
match *cx.typeck_results().node_type(e.hir_id).kind() {
|
||||
match *cx.typeck_results().node_type(hir_id).kind() {
|
||||
ty::Int(t) => {
|
||||
match lit.node {
|
||||
ast::LitKind::Int(v, ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed) => {
|
||||
lint_int_literal(cx, type_limits, e, lit, t, v.get())
|
||||
lint_int_literal(cx, type_limits, hir_id, span, lit, t, v.get())
|
||||
}
|
||||
_ => bug!(),
|
||||
};
|
||||
}
|
||||
ty::Uint(t) => lint_uint_literal(cx, e, lit, t),
|
||||
ty::Uint(t) => lint_uint_literal(cx, hir_id, span, lit, t),
|
||||
ty::Float(t) => {
|
||||
let (is_infinite, sym) = match lit.node {
|
||||
ast::LitKind::Float(v, _) => match t {
|
||||
|
@ -374,7 +383,7 @@ pub(crate) fn lint_literal<'tcx>(
|
|||
_ => bug!(),
|
||||
};
|
||||
if is_infinite == Ok(true) {
|
||||
cx.emit_span_lint(OVERFLOWING_LITERALS, e.span, OverflowingLiteral {
|
||||
cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingLiteral {
|
||||
ty: t.name_str(),
|
||||
lit: cx
|
||||
.sess()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue