about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <github333195615777966@oli-obk.de>2025-02-01 11:56:03 +0000
committerOli Scherer <github333195615777966@oli-obk.de>2025-02-05 11:25:44 +0000
commit9f5473f7ad7b0bc9a100d82a39142f714a2b48f7 (patch)
tree6e18c1a1f6e9bea50591d055b8446d5eda0c14d2
parentd1231eabf9fb80aed4c9645a2d38883faa18bab5 (diff)
downloadrust-9f5473f7ad7b0bc9a100d82a39142f714a2b48f7.tar.gz
rust-9f5473f7ad7b0bc9a100d82a39142f714a2b48f7.zip
Avoid passing around an `Expr` that is only needed for its HirId and its Span
-rw-r--r--compiler/rustc_lint/src/types.rs2
-rw-r--r--compiler/rustc_lint/src/types/literal.rs69
2 files changed, 40 insertions, 31 deletions
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 0060f33888e..3c8a7ada4bf 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -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()
diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs
index 4b5163522f8..7d49b260acc 100644
--- a/compiler/rustc_lint/src/types/literal.rs
+++ b/compiler/rustc_lint/src/types/literal.rs
@@ -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()