Skip to content

Commit 9f5473f

Browse files
committed
Avoid passing around an Expr that is only needed for its HirId and its Span
1 parent d1231ea commit 9f5473f

File tree

2 files changed

+40
-31
lines changed

2 files changed

+40
-31
lines changed

Diff for: compiler/rustc_lint/src/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
557557
}
558558
}
559559
}
560-
hir::ExprKind::Lit(lit) => lint_literal(cx, self, e, lit),
560+
hir::ExprKind::Lit(lit) => lint_literal(cx, self, e.hir_id, e.span, lit),
561561
hir::ExprKind::Call(path, [l, r])
562562
if let ExprKind::Path(ref qpath) = path.kind
563563
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()

Diff for: compiler/rustc_lint/src/types/literal.rs

+39-30
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use hir::{ExprKind, Node, is_range_literal};
22
use rustc_abi::{Integer, Size};
3+
use rustc_hir::HirId;
34
use rustc_middle::ty::Ty;
45
use rustc_middle::ty::layout::IntegerExt;
56
use rustc_middle::{bug, ty};
7+
use rustc_span::Span;
68
use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir};
79

810
use crate::LateContext;
@@ -21,21 +23,22 @@ fn lint_overflowing_range_endpoint<'tcx>(
2123
lit: &hir::Lit,
2224
lit_val: u128,
2325
max: u128,
24-
expr: &'tcx hir::Expr<'tcx>,
26+
hir_id: HirId,
27+
lit_span: Span,
2528
ty: &str,
2629
) -> bool {
2730
// Look past casts to support cases like `0..256 as u8`
28-
let (expr, lit_span) = if let Node::Expr(par_expr) = cx.tcx.parent_hir_node(expr.hir_id)
31+
let (hir_id, span) = if let Node::Expr(par_expr) = cx.tcx.parent_hir_node(hir_id)
2932
&& let ExprKind::Cast(_, _) = par_expr.kind
3033
{
31-
(par_expr, expr.span)
34+
(par_expr.hir_id, par_expr.span)
3235
} else {
33-
(expr, expr.span)
36+
(hir_id, lit_span)
3437
};
3538

3639
// We only want to handle exclusive (`..`) ranges,
3740
// which are represented as `ExprKind::Struct`.
38-
let Node::ExprField(field) = cx.tcx.parent_hir_node(expr.hir_id) else { return false };
41+
let Node::ExprField(field) = cx.tcx.parent_hir_node(hir_id) else { return false };
3942
let Node::Expr(struct_expr) = cx.tcx.parent_hir_node(field.hir_id) else { return false };
4043
if !is_range_literal(struct_expr) {
4144
return false;
@@ -45,7 +48,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
4548
// We can suggest using an inclusive range
4649
// (`..=`) instead only if it is the `end` that is
4750
// overflowing and only by 1.
48-
if !(end.expr.hir_id == expr.hir_id && lit_val - 1 == max) {
51+
if !(end.expr.hir_id == hir_id && lit_val - 1 == max) {
4952
return false;
5053
};
5154

@@ -57,7 +60,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
5760
_ => bug!(),
5861
};
5962

60-
let sub_sugg = if expr.span.lo() == lit_span.lo() {
63+
let sub_sugg = if span.lo() == lit_span.lo() {
6164
let Ok(start) = cx.sess().source_map().span_to_snippet(start.span) else { return false };
6265
UseInclusiveRange::WithoutParen {
6366
sugg: struct_expr.span.shrink_to_lo().to(lit_span.shrink_to_hi()),
@@ -67,7 +70,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
6770
}
6871
} else {
6972
UseInclusiveRange::WithParen {
70-
eq_sugg: expr.span.shrink_to_lo(),
73+
eq_sugg: span.shrink_to_lo(),
7174
lit_sugg: lit_span,
7275
literal: lit_val - 1,
7376
suffix,
@@ -125,7 +128,8 @@ fn get_bin_hex_repr(cx: &LateContext<'_>, lit: &hir::Lit) -> Option<String> {
125128

126129
fn report_bin_hex_error(
127130
cx: &LateContext<'_>,
128-
expr: &hir::Expr<'_>,
131+
hir_id: HirId,
132+
span: Span,
129133
ty: attr::IntType,
130134
size: Size,
131135
repr_str: String,
@@ -144,19 +148,19 @@ fn report_bin_hex_error(
144148
};
145149
let sign =
146150
if negative { OverflowingBinHexSign::Negative } else { OverflowingBinHexSign::Positive };
147-
let sub = get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative).map(
151+
let sub = get_type_suggestion(cx.typeck_results().node_type(hir_id), val, negative).map(
148152
|suggestion_ty| {
149153
if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
150154
let (sans_suffix, _) = repr_str.split_at(pos);
151-
OverflowingBinHexSub::Suggestion { span: expr.span, suggestion_ty, sans_suffix }
155+
OverflowingBinHexSub::Suggestion { span, suggestion_ty, sans_suffix }
152156
} else {
153157
OverflowingBinHexSub::Help { suggestion_ty }
154158
}
155159
},
156160
);
157161
let sign_bit_sub = (!negative)
158162
.then(|| {
159-
let ty::Int(int_ty) = cx.typeck_results().node_type(expr.hir_id).kind() else {
163+
let ty::Int(int_ty) = cx.typeck_results().node_type(hir_id).kind() else {
160164
return None;
161165
};
162166

@@ -177,7 +181,7 @@ fn report_bin_hex_error(
177181
};
178182

179183
Some(OverflowingBinHexSignBitSub {
180-
span: expr.span,
184+
span,
181185
lit_no_suffix,
182186
negative_val: actually.clone(),
183187
int_ty: int_ty.name_str(),
@@ -186,7 +190,7 @@ fn report_bin_hex_error(
186190
})
187191
.flatten();
188192

189-
cx.emit_span_lint(OVERFLOWING_LITERALS, expr.span, OverflowingBinHex {
193+
cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingBinHex {
190194
ty: t,
191195
lit: repr_str.clone(),
192196
dec: val,
@@ -236,23 +240,25 @@ fn literal_to_i128(val: u128, negative: bool) -> Option<i128> {
236240
fn lint_int_literal<'tcx>(
237241
cx: &LateContext<'tcx>,
238242
type_limits: &TypeLimits,
239-
e: &'tcx hir::Expr<'tcx>,
243+
hir_id: HirId,
244+
span: Span,
240245
lit: &hir::Lit,
241246
t: ty::IntTy,
242247
v: u128,
243248
) {
244249
let int_type = t.normalize(cx.sess().target.pointer_width);
245250
let (min, max) = int_ty_range(int_type);
246251
let max = max as u128;
247-
let negative = type_limits.negated_expr_id == Some(e.hir_id);
252+
let negative = type_limits.negated_expr_id == Some(hir_id);
248253

249254
// Detect literal value out of range [min, max] inclusive
250255
// avoiding use of -min to prevent overflow/panic
251256
if (negative && v > max + 1) || (!negative && v > max) {
252257
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
253258
report_bin_hex_error(
254259
cx,
255-
e,
260+
hir_id,
261+
span,
256262
attr::IntType::SignedInt(ty::ast_int_ty(t)),
257263
Integer::from_int_ty(cx, t).size(),
258264
repr_str,
@@ -262,18 +268,18 @@ fn lint_int_literal<'tcx>(
262268
return;
263269
}
264270

265-
if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
271+
if lint_overflowing_range_endpoint(cx, lit, v, max, hir_id, span, t.name_str()) {
266272
// The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
267273
return;
268274
}
269275

270-
let span = if negative { type_limits.negated_expr_span.unwrap() } else { e.span };
276+
let span = if negative { type_limits.negated_expr_span.unwrap() } else { span };
271277
let lit = cx
272278
.sess()
273279
.source_map()
274280
.span_to_snippet(span)
275281
.unwrap_or_else(|_| if negative { format!("-{v}") } else { v.to_string() });
276-
let help = get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative)
282+
let help = get_type_suggestion(cx.typeck_results().node_type(hir_id), v, negative)
277283
.map(|suggestion_ty| OverflowingIntHelp { suggestion_ty });
278284

279285
cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingInt {
@@ -288,7 +294,8 @@ fn lint_int_literal<'tcx>(
288294

289295
fn lint_uint_literal<'tcx>(
290296
cx: &LateContext<'tcx>,
291-
e: &'tcx hir::Expr<'tcx>,
297+
hir_id: HirId,
298+
span: Span,
292299
lit: &hir::Lit,
293300
t: ty::UintTy,
294301
) {
@@ -302,7 +309,7 @@ fn lint_uint_literal<'tcx>(
302309
};
303310

304311
if lit_val < min || lit_val > max {
305-
if let Node::Expr(par_e) = cx.tcx.parent_hir_node(e.hir_id) {
312+
if let Node::Expr(par_e) = cx.tcx.parent_hir_node(hir_id) {
306313
match par_e.kind {
307314
hir::ExprKind::Cast(..) => {
308315
if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {
@@ -316,14 +323,15 @@ fn lint_uint_literal<'tcx>(
316323
_ => {}
317324
}
318325
}
319-
if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
326+
if lint_overflowing_range_endpoint(cx, lit, lit_val, max, hir_id, span, t.name_str()) {
320327
// The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
321328
return;
322329
}
323330
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
324331
report_bin_hex_error(
325332
cx,
326-
e,
333+
hir_id,
334+
span,
327335
attr::IntType::UnsignedInt(ty::ast_uint_ty(t)),
328336
Integer::from_uint_ty(cx, t).size(),
329337
repr_str,
@@ -332,7 +340,7 @@ fn lint_uint_literal<'tcx>(
332340
);
333341
return;
334342
}
335-
cx.emit_span_lint(OVERFLOWING_LITERALS, e.span, OverflowingUInt {
343+
cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingUInt {
336344
ty: t.name_str(),
337345
lit: cx
338346
.sess()
@@ -348,19 +356,20 @@ fn lint_uint_literal<'tcx>(
348356
pub(crate) fn lint_literal<'tcx>(
349357
cx: &LateContext<'tcx>,
350358
type_limits: &TypeLimits,
351-
e: &'tcx hir::Expr<'tcx>,
359+
hir_id: HirId,
360+
span: Span,
352361
lit: &hir::Lit,
353362
) {
354-
match *cx.typeck_results().node_type(e.hir_id).kind() {
363+
match *cx.typeck_results().node_type(hir_id).kind() {
355364
ty::Int(t) => {
356365
match lit.node {
357366
ast::LitKind::Int(v, ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed) => {
358-
lint_int_literal(cx, type_limits, e, lit, t, v.get())
367+
lint_int_literal(cx, type_limits, hir_id, span, lit, t, v.get())
359368
}
360369
_ => bug!(),
361370
};
362371
}
363-
ty::Uint(t) => lint_uint_literal(cx, e, lit, t),
372+
ty::Uint(t) => lint_uint_literal(cx, hir_id, span, lit, t),
364373
ty::Float(t) => {
365374
let (is_infinite, sym) = match lit.node {
366375
ast::LitKind::Float(v, _) => match t {
@@ -374,7 +383,7 @@ pub(crate) fn lint_literal<'tcx>(
374383
_ => bug!(),
375384
};
376385
if is_infinite == Ok(true) {
377-
cx.emit_span_lint(OVERFLOWING_LITERALS, e.span, OverflowingLiteral {
386+
cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingLiteral {
378387
ty: t.name_str(),
379388
lit: cx
380389
.sess()

0 commit comments

Comments
 (0)