about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-03-20 05:51:22 +0100
committerGitHub <noreply@github.com>2024-03-20 05:51:22 +0100
commit4f3050b85a315eb11344d483466530805597c46b (patch)
tree2167b4eaa822e883d7ea34f59534a2984ff4c8a3
parentb7dcabe55e3b915ba9488dc374f752404c2c8945 (diff)
parent81d7d7aabd5cdfb1e574a7ebae0b884e3aad8dea (diff)
downloadrust-4f3050b85a315eb11344d483466530805597c46b.tar.gz
rust-4f3050b85a315eb11344d483466530805597c46b.zip
Rollup merge of #121543 - onur-ozkan:clippy-args, r=oli-obk
various clippy fixes

We need to keep the order of the given clippy lint rules before passing them.
Since clap doesn't offer any useful interface for this purpose out of the box,
we have to handle it manually.

Additionally, this PR makes `-D` rules work as expected. Previously, lint rules were limited to `-W`. By enabling `-D`, clippy began to complain numerous lines in the tree, all of which have been resolved in this PR as well.

Fixes #121481
cc `@matthiaskrgr`
-rw-r--r--compiler/rustc_ast/src/token.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs20
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs1
-rw-r--r--compiler/stable_mir/src/mir/alloc.rs8
-rw-r--r--library/std/src/io/buffered/bufreader.rs7
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs42
-rw-r--r--src/bootstrap/src/core/config/tests.rs54
11 files changed, 107 insertions, 37 deletions
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 5ccc7d51066..c17020ed663 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -11,6 +11,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
 use rustc_macros::HashStable_Generic;
 use rustc_span::symbol::{kw, sym};
+#[allow(clippy::useless_attribute)] // FIXME: following use of `hidden_glob_reexports` incorrectly triggers `useless_attribute` lint.
 #[allow(hidden_glob_reexports)]
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::{edition::Edition, ErrorGuaranteed, Span, DUMMY_SP};
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index c3f17563b0a..649ff9df2cc 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -315,6 +315,7 @@ pub unsafe fn create_module<'ll>(
     //
     // On the wasm targets it will get hooked up to the "producer" sections
     // `processed-by` information.
+    #[allow(clippy::option_env_unwrap)]
     let rustc_producer =
         format!("rustc version {}", option_env!("CFG_VERSION").expect("CFG_VERSION"));
     let name_metadata = llvm::LLVMMDStringInContext(
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 2f04f053bac..58eaef65e55 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -293,7 +293,9 @@ pub fn intern_const_alloc_for_constprop<
         return Ok(());
     }
     // Move allocation to `tcx`.
-    for _ in intern_shallow(ecx, alloc_id, Mutability::Not).map_err(|()| err_ub!(DeadLocal))? {
+    if let Some(_) =
+        (intern_shallow(ecx, alloc_id, Mutability::Not).map_err(|()| err_ub!(DeadLocal))?).next()
+    {
         // We are not doing recursive interning, so we don't currently support provenance.
         // (If this assertion ever triggers, we should just implement a
         // proper recursive interning loop -- or just call `intern_const_alloc_recursive`.
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 8dfd6f14cce..1bd2c88ebaa 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -2198,7 +2198,7 @@ impl<D: Decoder> Decodable<D> for EncodedMetadata {
         let mmap = if len > 0 {
             let mut mmap = MmapMut::map_anon(len).unwrap();
             for _ in 0..len {
-                (&mut mmap[..]).write(&[d.read_u8()]).unwrap();
+                (&mut mmap[..]).write_all(&[d.read_u8()]).unwrap();
             }
             mmap.flush().unwrap();
             Some(mmap.make_read_only().unwrap())
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index e8e80a8de50..5e74ce86007 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -76,20 +76,16 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
         if self.current_id == CRATE_HIR_ID {
             return None;
         }
-        loop {
-            // There are nodes that do not have entries, so we need to skip them.
-            let parent_id = self.map.def_key(self.current_id.owner.def_id).parent;
 
-            let parent_id = parent_id.map_or(CRATE_OWNER_ID, |local_def_index| {
-                let def_id = LocalDefId { local_def_index };
-                self.map.tcx.local_def_id_to_hir_id(def_id).owner
-            });
-            self.current_id = HirId::make_owner(parent_id.def_id);
+        let parent_id = self.map.def_key(self.current_id.owner.def_id).parent;
+        let parent_id = parent_id.map_or(CRATE_OWNER_ID, |local_def_index| {
+            let def_id = LocalDefId { local_def_index };
+            self.map.tcx.local_def_id_to_hir_id(def_id).owner
+        });
+        self.current_id = HirId::make_owner(parent_id.def_id);
 
-            // If this `HirId` doesn't have an entry, skip it and look for its `parent_id`.
-            let node = self.map.tcx.hir_owner_node(self.current_id.owner);
-            return Some((self.current_id.owner, node));
-        }
+        let node = self.map.tcx.hir_owner_node(self.current_id.owner);
+        return Some((self.current_id.owner, node));
     }
 }
 
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index f9edbb3c5ae..6275942bafe 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -671,11 +671,11 @@ pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result<u128, i
     // So we do not read exactly 16 bytes into the u128, just the "payload".
     let uint = match endianness {
         Endian::Little => {
-            source.read(&mut buf)?;
+            source.read_exact(&mut buf[..source.len()])?;
             Ok(u128::from_le_bytes(buf))
         }
         Endian::Big => {
-            source.read(&mut buf[16 - source.len()..])?;
+            source.read_exact(&mut buf[16 - source.len()..])?;
             Ok(u128::from_be_bytes(buf))
         }
     };
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index e7808ff880b..d2cbbf9be32 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -229,7 +229,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         span: Span,
         scrutinee_span: Span,
     ) -> BlockAnd<()> {
-        let scrutinee_span = scrutinee_span;
         let scrutinee_place =
             unpack!(block = self.lower_scrutinee(block, scrutinee_id, scrutinee_span));
 
diff --git a/compiler/stable_mir/src/mir/alloc.rs b/compiler/stable_mir/src/mir/alloc.rs
index c780042ff26..66457933438 100644
--- a/compiler/stable_mir/src/mir/alloc.rs
+++ b/compiler/stable_mir/src/mir/alloc.rs
@@ -57,11 +57,11 @@ pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> {
     let mut buf = [0u8; std::mem::size_of::<u128>()];
     match MachineInfo::target_endianess() {
         Endian::Little => {
-            bytes.read(&mut buf)?;
+            bytes.read_exact(&mut buf[..bytes.len()])?;
             Ok(u128::from_le_bytes(buf))
         }
         Endian::Big => {
-            bytes.read(&mut buf[16 - bytes.len()..])?;
+            bytes.read_exact(&mut buf[16 - bytes.len()..])?;
             Ok(u128::from_be_bytes(buf))
         }
     }
@@ -72,11 +72,11 @@ pub(crate) fn read_target_int(mut bytes: &[u8]) -> Result<i128, Error> {
     let mut buf = [0u8; std::mem::size_of::<i128>()];
     match MachineInfo::target_endianess() {
         Endian::Little => {
-            bytes.read(&mut buf)?;
+            bytes.read_exact(&mut buf[..bytes.len()])?;
             Ok(i128::from_le_bytes(buf))
         }
         Endian::Big => {
-            bytes.read(&mut buf[16 - bytes.len()..])?;
+            bytes.read_exact(&mut buf[16 - bytes.len()..])?;
             Ok(i128::from_be_bytes(buf))
         }
     }
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 83db332ee25..acaa7e9228e 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -328,10 +328,9 @@ impl<R: ?Sized + Read> Read for BufReader<R> {
             self.discard_buffer();
             return self.inner.read_vectored(bufs);
         }
-        let nread = {
-            let mut rem = self.fill_buf()?;
-            rem.read_vectored(bufs)?
-        };
+        let mut rem = self.fill_buf()?;
+        let nread = rem.read_vectored(bufs)?;
+
         self.consume(nread);
         Ok(nread)
     }
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index a90139a070a..55180a82885 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -61,14 +61,16 @@ fn args(builder: &Builder<'_>) -> Vec<String> {
             }
         }
 
-        args.extend(strings(&["--", "--cap-lints", "warn"]));
+        args.extend(strings(&["--"]));
+
+        if deny.is_empty() && forbid.is_empty() {
+            args.extend(strings(&["--cap-lints", "warn"]));
+        }
+
+        let all_args = std::env::args().collect::<Vec<_>>();
+        args.extend(get_clippy_rules_in_order(&all_args, allow, deny, warn, forbid));
+
         args.extend(ignored_lints.iter().map(|lint| format!("-Aclippy::{}", lint)));
-        let mut clippy_lint_levels: Vec<String> = Vec::new();
-        allow.iter().for_each(|v| clippy_lint_levels.push(format!("-A{}", v)));
-        deny.iter().for_each(|v| clippy_lint_levels.push(format!("-D{}", v)));
-        warn.iter().for_each(|v| clippy_lint_levels.push(format!("-W{}", v)));
-        forbid.iter().for_each(|v| clippy_lint_levels.push(format!("-F{}", v)));
-        args.extend(clippy_lint_levels);
         args.extend(builder.config.free_args.clone());
         args
     } else {
@@ -76,6 +78,32 @@ fn args(builder: &Builder<'_>) -> Vec<String> {
     }
 }
 
+/// We need to keep the order of the given clippy lint rules before passing them.
+/// Since clap doesn't offer any useful interface for this purpose out of the box,
+/// we have to handle it manually.
+pub(crate) fn get_clippy_rules_in_order(
+    all_args: &[String],
+    allow_rules: &[String],
+    deny_rules: &[String],
+    warn_rules: &[String],
+    forbid_rules: &[String],
+) -> Vec<String> {
+    let mut result = vec![];
+
+    for (prefix, item) in
+        [("-A", allow_rules), ("-D", deny_rules), ("-W", warn_rules), ("-F", forbid_rules)]
+    {
+        item.iter().for_each(|v| {
+            let rule = format!("{prefix}{v}");
+            let position = all_args.iter().position(|t| t == &rule).unwrap();
+            result.push((position, rule));
+        });
+    }
+
+    result.sort_by_key(|&(position, _)| position);
+    result.into_iter().map(|v| v.1).collect()
+}
+
 fn cargo_subcommand(kind: Kind) -> &'static str {
     match kind {
         Kind::Check => "check",
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index 93ba5f4120a..8cd538953c5 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -1,4 +1,5 @@
 use super::{flags::Flags, ChangeIdWrapper, Config};
+use crate::core::build_steps::check::get_clippy_rules_in_order;
 use crate::core::config::{LldMode, TomlConfig};
 
 use clap::CommandFactory;
@@ -11,12 +12,13 @@ use std::{
 };
 
 fn parse(config: &str) -> Config {
-    let config = format!("{config} \r\n build.rustc = \"/does-not-exists\" ");
     Config::parse_inner(
         &[
-            "check".to_owned(),
-            "--config=/does/not/exist".to_owned(),
-            "--skip-stage0-validation".to_owned(),
+            "check".to_string(),
+            "--set=build.rustc=/does/not/exist".to_string(),
+            "--set=build.cargo=/does/not/exist".to_string(),
+            "--config=/does/not/exist".to_string(),
+            "--skip-stage0-validation".to_string(),
         ],
         |&_| toml::from_str(&config).unwrap(),
     )
@@ -169,7 +171,10 @@ fn override_toml_duplicate() {
     Config::parse_inner(
         &[
             "check".to_owned(),
+            "--set=build.rustc=/does/not/exist".to_string(),
+            "--set=build.cargo=/does/not/exist".to_string(),
             "--config=/does/not/exist".to_owned(),
+            "--skip-stage0-validation".to_owned(),
             "--set=change-id=1".to_owned(),
             "--set=change-id=2".to_owned(),
         ],
@@ -192,7 +197,15 @@ fn profile_user_dist() {
             .and_then(|table: toml::Value| TomlConfig::deserialize(table))
             .unwrap()
     }
-    Config::parse_inner(&["check".to_owned()], get_toml);
+    Config::parse_inner(
+        &[
+            "check".to_owned(),
+            "--set=build.rustc=/does/not/exist".to_string(),
+            "--set=build.cargo=/does/not/exist".to_string(),
+            "--skip-stage0-validation".to_string(),
+        ],
+        get_toml,
+    );
 }
 
 #[test]
@@ -254,3 +267,34 @@ fn parse_change_id_with_unknown_field() {
     let change_id_wrapper: ChangeIdWrapper = toml::from_str(config).unwrap();
     assert_eq!(change_id_wrapper.inner, Some(3461));
 }
+
+#[test]
+fn order_of_clippy_rules() {
+    let args = vec![
+        "clippy".to_string(),
+        "--fix".to_string(),
+        "--allow-dirty".to_string(),
+        "--allow-staged".to_string(),
+        "-Aclippy:all".to_string(),
+        "-Wclippy::style".to_string(),
+        "-Aclippy::foo1".to_string(),
+        "-Aclippy::foo2".to_string(),
+    ];
+    let config = Config::parse(&args);
+
+    let actual = match &config.cmd {
+        crate::Subcommand::Clippy { allow, deny, warn, forbid, .. } => {
+            get_clippy_rules_in_order(&args, &allow, &deny, &warn, &forbid)
+        }
+        _ => panic!("invalid subcommand"),
+    };
+
+    let expected = vec![
+        "-Aclippy:all".to_string(),
+        "-Wclippy::style".to_string(),
+        "-Aclippy::foo1".to_string(),
+        "-Aclippy::foo2".to_string(),
+    ];
+
+    assert_eq!(expected, actual);
+}