summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_lint/src/types.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_lint/src/types.rs')
-rw-r--r--compiler/rustc_lint/src/types.rs42
1 files changed, 31 insertions, 11 deletions
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 85958c417..a6ba74220 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -4,7 +4,8 @@ use crate::{
AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes,
InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign,
OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral,
- OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag,
+ OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons, UseInclusiveRange,
+ VariantSizeDifferencesDiag,
},
};
use crate::{LateContext, LateLintPass, LintContext};
@@ -17,7 +18,7 @@ use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{
- self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
+ self, AdtKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
use rustc_span::def_id::LocalDefId;
use rustc_span::source_map;
@@ -136,6 +137,14 @@ fn lint_overflowing_range_endpoint<'tcx>(
expr: &'tcx hir::Expr<'tcx>,
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.hir().get(cx.tcx.hir().parent_id(expr.hir_id))
+ && let ExprKind::Cast(_, _) = par_expr.kind {
+ (par_expr, expr.span)
+ } else {
+ (expr, expr.span)
+ };
+
// We only want to handle exclusive (`..`) ranges,
// which are represented as `ExprKind::Struct`.
let par_id = cx.tcx.hir().parent_id(expr.hir_id);
@@ -155,7 +164,6 @@ fn lint_overflowing_range_endpoint<'tcx>(
if !(eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max) {
return false;
};
- let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) else { return false };
use rustc_ast::{LitIntType, LitKind};
let suffix = match lit.node {
@@ -164,16 +172,28 @@ fn lint_overflowing_range_endpoint<'tcx>(
LitKind::Int(_, LitIntType::Unsuffixed) => "",
_ => bug!(),
};
- cx.emit_spanned_lint(
- OVERFLOWING_LITERALS,
- struct_expr.span,
- RangeEndpointOutOfRange {
- ty,
- suggestion: struct_expr.span,
+
+ let sub_sugg = if expr.span.lo() == lit_span.lo() {
+ let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) else { return false };
+ UseInclusiveRange::WithoutParen {
+ sugg: struct_expr.span.shrink_to_lo().to(lit_span.shrink_to_hi()),
start,
literal: lit_val - 1,
suffix,
- },
+ }
+ } else {
+ UseInclusiveRange::WithParen {
+ eq_sugg: expr.span.shrink_to_lo(),
+ lit_sugg: lit_span,
+ literal: lit_val - 1,
+ suffix,
+ }
+ };
+
+ cx.emit_spanned_lint(
+ OVERFLOWING_LITERALS,
+ struct_expr.span,
+ RangeEndpointOutOfRange { ty, sub: sub_sugg },
);
// We've just emitted a lint, special cased for `(...)..MAX+1` ranges,
@@ -750,7 +770,7 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty);
if let ty::Adt(ty_def, substs) = ty.kind() {
let field_ty = match &ty_def.variants().raw[..] {
- [var_one, var_two] => match (&var_one.fields[..], &var_two.fields[..]) {
+ [var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) {
([], [field]) | ([field], []) => field.ty(cx.tcx, substs),
_ => return None,
},