]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_lint/src/types.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / compiler / rustc_lint / src / types.rs
index 5c07afeb7aa8f73f0794bbb3ba26c5a55131ee2f..4fb6d65a6e98f4f86db64f3975bc73a5809fe042 100644 (file)
@@ -19,7 +19,6 @@ use rustc_target::spec::abi::Abi as SpecAbi;
 use std::cmp;
 use std::iter;
 use std::ops::ControlFlow;
-use tracing::debug;
 
 declare_lint! {
     /// The `unused_comparisons` lint detects comparisons made useless by
@@ -125,45 +124,51 @@ fn lint_overflowing_range_endpoint<'tcx>(
     lit_val: u128,
     max: u128,
     expr: &'tcx hir::Expr<'tcx>,
-    parent_expr: &'tcx hir::Expr<'tcx>,
     ty: &str,
 ) -> bool {
     // We only want to handle exclusive (`..`) ranges,
     // which are represented as `ExprKind::Struct`.
+    let par_id = cx.tcx.hir().get_parent_node(expr.hir_id);
+    let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false };
+    let field_par_id = cx.tcx.hir().get_parent_node(field.hir_id);
+    let Node::Expr(struct_expr) = cx.tcx.hir().get(field_par_id) else { return false };
+    if !is_range_literal(struct_expr) {
+        return false;
+    };
+    let ExprKind::Struct(_, eps, _) = &struct_expr.kind else { return false };
+    if eps.len() != 2 {
+        return false;
+    }
+
     let mut overwritten = false;
-    if let ExprKind::Struct(_, eps, _) = &parent_expr.kind {
-        if eps.len() != 2 {
-            return false;
-        }
-        // We can suggest using an inclusive range
-        // (`..=`) instead only if it is the `end` that is
-        // overflowing and only by 1.
-        if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
-            cx.struct_span_lint(OVERFLOWING_LITERALS, parent_expr.span, |lint| {
-                let mut err = lint.build(fluent::lint::range_endpoint_out_of_range);
-                err.set_arg("ty", ty);
-                if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
-                    use ast::{LitIntType, LitKind};
-                    // We need to preserve the literal's suffix,
-                    // as it may determine typing information.
-                    let suffix = match lit.node {
-                        LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
-                        LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
-                        LitKind::Int(_, LitIntType::Unsuffixed) => "",
-                        _ => bug!(),
-                    };
-                    let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
-                    err.span_suggestion(
-                        parent_expr.span,
-                        fluent::lint::suggestion,
-                        suggestion,
-                        Applicability::MachineApplicable,
-                    );
-                    err.emit();
-                    overwritten = true;
-                }
-            });
-        }
+    // We can suggest using an inclusive range
+    // (`..=`) instead only if it is the `end` that is
+    // overflowing and only by 1.
+    if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
+        cx.struct_span_lint(OVERFLOWING_LITERALS, struct_expr.span, |lint| {
+            let mut err = lint.build(fluent::lint::range_endpoint_out_of_range);
+            err.set_arg("ty", ty);
+            if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
+                use ast::{LitIntType, LitKind};
+                // We need to preserve the literal's suffix,
+                // as it may determine typing information.
+                let suffix = match lit.node {
+                    LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
+                    LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
+                    LitKind::Int(_, LitIntType::Unsuffixed) => "",
+                    _ => bug!(),
+                };
+                let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
+                err.span_suggestion(
+                    struct_expr.span,
+                    fluent::lint::suggestion,
+                    suggestion,
+                    Applicability::MachineApplicable,
+                );
+                err.emit();
+                overwritten = true;
+            }
+        });
     }
     overwritten
 }
@@ -339,16 +344,9 @@ fn lint_int_literal<'tcx>(
             return;
         }
 
-        let par_id = cx.tcx.hir().get_parent_node(e.hir_id);
-        if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
-            if let hir::ExprKind::Struct(..) = par_e.kind {
-                if is_range_literal(par_e)
-                    && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
-                {
-                    // The overflowing literal lint was overridden.
-                    return;
-                }
-            }
+        if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
+            // The overflowing literal lint was overridden.
+            return;
         }
 
         cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
@@ -408,16 +406,13 @@ fn lint_uint_literal<'tcx>(
                         return;
                     }
                 }
-                hir::ExprKind::Struct(..) if is_range_literal(par_e) => {
-                    let t = t.name_str();
-                    if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
-                        // The overflowing literal lint was overridden.
-                        return;
-                    }
-                }
                 _ => {}
             }
         }
+        if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
+            // The overflowing literal lint was overridden.
+            return;
+        }
         if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
             report_bin_hex_error(
                 cx,
@@ -724,7 +719,7 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
     Some(match *ty.kind() {
         ty::Adt(field_def, field_substs) => {
             let inner_field_ty = {
-                let first_non_zst_ty = field_def
+                let mut first_non_zst_ty = field_def
                     .variants()
                     .iter()
                     .filter_map(|v| transparent_newtype_field(cx.tcx, v));
@@ -734,7 +729,7 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
                     "Wrong number of fields for transparent type"
                 );
                 first_non_zst_ty
-                    .last()
+                    .next_back()
                     .expect("No non-zst fields in transparent type.")
                     .ty(tcx, field_substs)
             };
@@ -1463,7 +1458,7 @@ impl InvalidAtomicOrdering {
             sym::AtomicI64,
             sym::AtomicI128,
         ];
-        if let ExprKind::MethodCall(ref method_path, args, _) = &expr.kind
+        if let ExprKind::MethodCall(ref method_path, _, args, _) = &expr.kind
             && recognized_names.contains(&method_path.ident.name)
             && let Some(m_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
             && let Some(impl_did) = cx.tcx.impl_of_method(m_def_id)
@@ -1499,8 +1494,8 @@ impl InvalidAtomicOrdering {
     fn check_atomic_load_store(cx: &LateContext<'_>, expr: &Expr<'_>) {
         if let Some((method, args)) = Self::inherent_atomic_method_call(cx, expr, &[sym::load, sym::store])
             && let Some((ordering_arg, invalid_ordering)) = match method {
-                sym::load => Some((&args[1], sym::Release)),
-                sym::store => Some((&args[2], sym::Acquire)),
+                sym::load => Some((&args[0], sym::Release)),
+                sym::store => Some((&args[1], sym::Acquire)),
                 _ => None,
             }
             && let Some(ordering) = Self::match_ordering(cx, ordering_arg)
@@ -1541,8 +1536,8 @@ impl InvalidAtomicOrdering {
             else {return };
 
         let fail_order_arg = match method {
-            sym::fetch_update => &args[2],
-            sym::compare_exchange | sym::compare_exchange_weak => &args[4],
+            sym::fetch_update => &args[1],
+            sym::compare_exchange | sym::compare_exchange_weak => &args[3],
             _ => return,
         };
 
@@ -1550,7 +1545,7 @@ impl InvalidAtomicOrdering {
 
         if matches!(fail_ordering, sym::Release | sym::AcqRel) {
             #[derive(LintDiagnostic)]
-            #[lint(lint::atomic_ordering_invalid)]
+            #[diag(lint::atomic_ordering_invalid)]
             #[help]
             struct InvalidAtomicOrderingDiag {
                 method: Symbol,