Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0a8b81e
Ensure that we never try to monomorphize the upcasting of impossible …
compiler-errors Jan 18, 2025
382caf9
Use short ty string for binop and upops errors
estebank Jan 30, 2025
ee17c3b
Don't demand `&Box<Pat>` in `print_pat`
Zalathar Jan 28, 2025
849e036
Remove `'pat` lifetime from some match-lowering data structures
Zalathar Feb 2, 2025
d72cc93
Remove some non-trivial `box` patterns
Zalathar Feb 2, 2025
869c7b7
Avoid double-boxing lists of THIR subpatterns
Zalathar Feb 2, 2025
2f16696
Slightly simplify the signature of `lower_match_arms`
Zalathar Feb 2, 2025
d1231ea
Add regression test
oli-obk Jan 31, 2025
9f5473f
Avoid passing around an `Expr` that is only needed for its HirId and …
oli-obk Feb 1, 2025
9a2073d
Uniformly handle HIR literals in visitors and lints
oli-obk Feb 1, 2025
ab31159
Pretty print pattern type values with `transmute` if they don't satis…
oli-obk Jan 29, 2025
d0b0b02
Eagerly detect coroutine recursion pre-mono when possible
compiler-errors Jan 27, 2025
51bc4c9
bootstrap: reset some test suite metadata when starting a new test suite
jieyouxu Feb 6, 2025
9c5f025
tests(std): don't output to std{out,err} in `test_creation_flags` and…
jieyouxu Feb 6, 2025
7ca2936
Rollup merge of #136073 - compiler-errors:recursive-coro-always, r=ol…
matthiaskrgr Feb 6, 2025
62cad97
Rollup merge of #136235 - oli-obk:transmuty-pat-tys, r=RalfJung
matthiaskrgr Feb 6, 2025
b62f318
Rollup merge of #136311 - compiler-errors:vtable-fixes-2, r=lcnr
matthiaskrgr Feb 6, 2025
c2c4d5e
Rollup merge of #136315 - estebank:long-ty-binop, r=SparrowLii
matthiaskrgr Feb 6, 2025
85a9de5
Rollup merge of #136393 - oli-obk:pattern-type-lit-oflo-checks, r=com…
matthiaskrgr Feb 6, 2025
c9635e5
Rollup merge of #136435 - Zalathar:thir-pat-stuff, r=Nadrieril
matthiaskrgr Feb 6, 2025
5b22425
Rollup merge of #136630 - jieyouxu:render_tests, r=ChrisDenton
matthiaskrgr Feb 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Avoid passing around an Expr that is only needed for its HirId and …
…its Span
  • Loading branch information
oli-obk committed Feb 5, 2025
commit 9f5473f7ad7b0bc9a100d82a39142f714a2b48f7
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
69 changes: 39 additions & 30 deletions compiler/rustc_lint/src/types/literal.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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;
};

Expand All @@ -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()),
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -144,19 +148,19 @@ 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 }
}
},
);
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;
};

Expand All @@ -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(),
Expand All @@ -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,
Expand Down Expand Up @@ -236,23 +240,25 @@ 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,
) {
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
if (negative && v > max + 1) || (!negative && v > max) {
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,
Expand All @@ -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 {
Expand All @@ -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,
) {
Expand All @@ -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() {
Expand All @@ -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,
Expand All @@ -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()
Expand All @@ -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 {
Expand All @@ -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()
Expand Down